aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2014-11-20 10:40:00 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2014-11-20 10:40:00 -0500
commit91c77947133f7aef851b625701e182d3f99d14a9 (patch)
tree9ba1e0db29e4b7e6835d32bae45ec45b62371896 /fs
parent521484639ec19a6f1ed56de6993feb255f5f676c (diff)
ovl: allow filenames with comma
Allow option separator (comma) to be escaped with backslash. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/super.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index b92bd1829cf7..eee7a62e1c0e 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -462,11 +462,34 @@ static const match_table_t ovl_tokens = {
462 {OPT_ERR, NULL} 462 {OPT_ERR, NULL}
463}; 463};
464 464
465static 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
465static int ovl_parse_opt(char *opt, struct ovl_config *config) 488static int ovl_parse_opt(char *opt, struct ovl_config *config)
466{ 489{
467 char *p; 490 char *p;
468 491
469 while ((p = strsep(&opt, ",")) != NULL) { 492 while ((p = ovl_next_opt(&opt)) != NULL) {
470 int token; 493 int token;
471 substring_t args[MAX_OPT_ARGS]; 494 substring_t args[MAX_OPT_ARGS];
472 495
@@ -554,15 +577,34 @@ out_dput:
554 goto out_unlock; 577 goto out_unlock;
555} 578}
556 579
580static 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
557static int ovl_mount_dir(const char *name, struct path *path) 593static int ovl_mount_dir(const char *name, struct path *path)
558{ 594{
559 int err; 595 int err;
596 char *tmp = kstrdup(name, GFP_KERNEL);
597
598 if (!tmp)
599 return -ENOMEM;
560 600
561 err = kern_path(name, LOOKUP_FOLLOW, path); 601 ovl_unescape(tmp);
602 err = kern_path(tmp, LOOKUP_FOLLOW, path);
562 if (err) { 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 err = -EINVAL; 605 err = -EINVAL;
565 } 606 }
607 kfree(tmp);
566 return err; 608 return err;
567} 609}
568 610