Commit 74efd61a75f1a400aa480ad08231ba31ccdec895
Committed by
Anthony Liguori
1 parent
229609dd
slirp: tftp: Relax filename format check
[ Applies on top of my recently posted slirp series. ] Allow tftp requests with filenames that do not start with a slash. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
1 changed file
with
5 additions
and
3 deletions
slirp/tftp.c
| @@ -284,11 +284,12 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) | @@ -284,11 +284,12 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) | ||
| 284 | 284 | ||
| 285 | /* prepend tftp_prefix */ | 285 | /* prepend tftp_prefix */ |
| 286 | prefix_len = strlen(slirp->tftp_prefix); | 286 | prefix_len = strlen(slirp->tftp_prefix); |
| 287 | - spt->filename = qemu_malloc(prefix_len + TFTP_FILENAME_MAX + 1); | 287 | + spt->filename = qemu_malloc(prefix_len + TFTP_FILENAME_MAX + 2); |
| 288 | memcpy(spt->filename, slirp->tftp_prefix, prefix_len); | 288 | memcpy(spt->filename, slirp->tftp_prefix, prefix_len); |
| 289 | + spt->filename[prefix_len] = '/'; | ||
| 289 | 290 | ||
| 290 | /* get name */ | 291 | /* get name */ |
| 291 | - req_fname = spt->filename + prefix_len; | 292 | + req_fname = spt->filename + prefix_len + 1; |
| 292 | 293 | ||
| 293 | while (1) { | 294 | while (1) { |
| 294 | if (k >= TFTP_FILENAME_MAX || k >= pktlen) { | 295 | if (k >= TFTP_FILENAME_MAX || k >= pktlen) { |
| @@ -315,7 +316,8 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) | @@ -315,7 +316,8 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) | ||
| 315 | k += 6; /* skipping octet */ | 316 | k += 6; /* skipping octet */ |
| 316 | 317 | ||
| 317 | /* do sanity checks on the filename */ | 318 | /* do sanity checks on the filename */ |
| 318 | - if (req_fname[0] != '/' || req_fname[strlen(req_fname) - 1] == '/' || | 319 | + if (!strncmp(req_fname, "../", 3) || |
| 320 | + req_fname[strlen(req_fname) - 1] == '/' || | ||
| 319 | strstr(req_fname, "/../")) { | 321 | strstr(req_fname, "/../")) { |
| 320 | tftp_send_error(spt, 2, "Access violation", tp); | 322 | tftp_send_error(spt, 2, "Access violation", tp); |
| 321 | return; | 323 | return; |