Commit 91c77947133f7aef851b625701e182d3f99d14a9
1 parent
521484639e
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
ovl: allow filenames with comma
Allow option separator (comma) to be escaped with backslash. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Showing 1 changed file with 45 additions and 3 deletions Side-by-side Diff
fs/overlayfs/super.c
... | ... | @@ -462,11 +462,34 @@ |
462 | 462 | {OPT_ERR, NULL} |
463 | 463 | }; |
464 | 464 | |
465 | +static char *ovl_next_opt(char **s) | |
466 | +{ | |
467 | + char *sbegin = *s; | |
468 | + char *p; | |
469 | + | |
470 | + if (sbegin == NULL) | |
471 | + return NULL; | |
472 | + | |
473 | + for (p = sbegin; *p; p++) { | |
474 | + if (*p == '\\') { | |
475 | + p++; | |
476 | + if (!*p) | |
477 | + break; | |
478 | + } else if (*p == ',') { | |
479 | + *p = '\0'; | |
480 | + *s = p + 1; | |
481 | + return sbegin; | |
482 | + } | |
483 | + } | |
484 | + *s = NULL; | |
485 | + return sbegin; | |
486 | +} | |
487 | + | |
465 | 488 | static int ovl_parse_opt(char *opt, struct ovl_config *config) |
466 | 489 | { |
467 | 490 | char *p; |
468 | 491 | |
469 | - while ((p = strsep(&opt, ",")) != NULL) { | |
492 | + while ((p = ovl_next_opt(&opt)) != NULL) { | |
470 | 493 | int token; |
471 | 494 | substring_t args[MAX_OPT_ARGS]; |
472 | 495 | |
473 | 496 | |
474 | 497 | |
475 | 498 | |
476 | 499 | |
... | ... | @@ -554,15 +577,34 @@ |
554 | 577 | goto out_unlock; |
555 | 578 | } |
556 | 579 | |
580 | +static void ovl_unescape(char *s) | |
581 | +{ | |
582 | + char *d = s; | |
583 | + | |
584 | + for (;; s++, d++) { | |
585 | + if (*s == '\\') | |
586 | + s++; | |
587 | + *d = *s; | |
588 | + if (!*s) | |
589 | + break; | |
590 | + } | |
591 | +} | |
592 | + | |
557 | 593 | static int ovl_mount_dir(const char *name, struct path *path) |
558 | 594 | { |
559 | 595 | int err; |
596 | + char *tmp = kstrdup(name, GFP_KERNEL); | |
560 | 597 | |
561 | - err = kern_path(name, LOOKUP_FOLLOW, path); | |
598 | + if (!tmp) | |
599 | + return -ENOMEM; | |
600 | + | |
601 | + ovl_unescape(tmp); | |
602 | + err = kern_path(tmp, LOOKUP_FOLLOW, path); | |
562 | 603 | if (err) { |
563 | - pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); | |
604 | + pr_err("overlayfs: failed to resolve '%s': %i\n", tmp, err); | |
564 | 605 | err = -EINVAL; |
565 | 606 | } |
607 | + kfree(tmp); | |
566 | 608 | return err; |
567 | 609 | } |
568 | 610 |