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; |