bcachefs: Fix error in parsing of mount options
authorDan Robertson <dan@dlrobertson.com>
Sun, 9 May 2021 22:52:23 +0000 (18:52 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:03 +0000 (17:09 -0400)
When parsing the mount options duplicate the given options. This is
required as the options are parsed twice and strsep is used in parsing.
The options will be modified into a possibly invalid options set for the
second round of parsing if the options are not duplicated before
parsing.

Signed-off-by: Dan Robertson <dan@dlrobertson.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/opts.c

index 0cfbb56a57c103211c2761603747f65f17fb41a2..64bf5a382d63574da713321185f626a413c7932f 100644 (file)
@@ -315,11 +315,20 @@ int bch2_opts_check_may_set(struct bch_fs *c)
 int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
                          char *options)
 {
+       char *copied_opts, *copied_opts_start;
        char *opt, *name, *val;
        int ret, id;
        u64 v;
 
-       while ((opt = strsep(&options, ",")) != NULL) {
+       if (!options)
+               return 0;
+
+       copied_opts = kstrdup(options, GFP_KERNEL);
+       if (!copied_opts)
+               return -1;
+       copied_opts_start = copied_opts;
+
+       while ((opt = strsep(&copied_opts, ",")) != NULL) {
                name    = strsep(&opt, "=");
                val     = opt;
 
@@ -363,16 +372,24 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
                bch2_opt_set_by_id(opts, id, v);
        }
 
-       return 0;
+       ret = 0;
+       goto out;
+
 bad_opt:
        pr_err("Bad mount option %s", name);
-       return -1;
+       ret = -1;
+       goto out;
 bad_val:
        pr_err("Invalid value %s for mount option %s", val, name);
-       return -1;
+       ret = -1;
+       goto out;
 no_val:
        pr_err("Mount option %s requires a value", name);
-       return -1;
+       ret = -1;
+       goto out;
+out:
+       kfree(copied_opts_start);
+       return ret;
 }
 
 /* io opts: */