]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: make sure "option=" is used as string
authorKarel Zak <kzak@redhat.com>
Wed, 20 Mar 2024 15:08:16 +0000 (16:08 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 2 Apr 2024 11:01:12 +0000 (13:01 +0200)
mount(8) cares about case when option specified as "name=" (it means
without data). See for example 727c689908c5e68c92aa1dd65e0d3bdb6d91c1e5.

We need this also for new mount API and use FSCONFIG_SET_STRING rather
than FSCONFIG_SET_FLAG.

strace -e fsconfig ./mount -o usrjquota= /dev/sdc1 /mnt/test

Old:
fsconfig(3, FSCONFIG_SET_STRING, "source", "/dev/sdc1", 0) = 0
fsconfig(3, FSCONFIG_SET_FLAG, "usrjquota", NULL, 0) = -1 EINVAL (Invalid argument)

Fixed:
fsconfig(3, FSCONFIG_SET_STRING, "source", "/dev/sdc1", 0) = 0
fsconfig(3, FSCONFIG_SET_STRING, "usrjquota", "", 0) = 0

Fixes: https://github.com/util-linux/util-linux/issues/2837
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit 0c5485348b155420ecd1bfcdabb1b869ca5ee3c2)
(cherry picked from commit 175af5cb8e0434bbc6660f7ccbea3a188d8f2d72)

libmount/src/hook_mount.c
libmount/src/mountP.h
libmount/src/optlist.c

index dc3dfa71ad3190d2bb9d3d84a8da7ca660e3a037..4dc4c75d8670efb865fb34f934e9c5b96607827b 100644 (file)
@@ -181,6 +181,9 @@ static int configure_superblock(struct libmnt_context *cxt,
                        /* Ignore VFS flags, userspace and external options */
                        continue;
 
+               if (!value && mnt_opt_is_sepnodata(opt))
+                       value = "";     /* force use the value as string */
+
                rc = fsconfig_set_value(cxt, hs, fd, name, value);
                if (rc != 0)
                        goto done;
index 339e2761a5305d841ebaffd1ca5df1c5529db262..b978e7e6765ebf252d1aa218d333c01edd4a89e6 100644 (file)
@@ -601,6 +601,7 @@ extern int mnt_opt_set_value(struct libmnt_opt *opt, const char *str);
 extern int mnt_opt_set_u64value(struct libmnt_opt *opt, uint64_t num);
 extern int mnt_opt_set_quoted_value(struct libmnt_opt *opt, const char *str);
 extern int mnt_opt_is_external(struct libmnt_opt *opt);
+extern int mnt_opt_is_sepnodata(struct libmnt_opt *opt);
 
 /* fs.c */
 extern int mnt_fs_follow_optlist(struct libmnt_fs *fs, struct libmnt_optlist *ol);
index 0702adae7036f10314f32714cd13754d8bfed60b..65f8eccdf6e8365238a3dd22ce3cc7a62ba46047 100644 (file)
@@ -46,6 +46,7 @@ struct libmnt_opt {
 
        unsigned int external : 1,      /* visible for external helpers only */
                     recursive : 1,     /* recursive flag */
+                    sepnodata : 1,     /* value separator, but without data ("name=") */
                     is_linux : 1,      /* defined in ls->linux_map (VFS attr) */
                     quoted : 1;        /* name="value" */
 };
@@ -438,6 +439,10 @@ static struct libmnt_opt *optlist_new_opt(struct libmnt_optlist *ls,
                opt->value = strndup(value, valsz);
                if (!opt->value)
                        goto fail;
+
+       } else if (value) {
+               /* separator specified, but empty value ("name=") */
+               opt->sepnodata = 1;
        }
        if (namesz) {
                opt->name = strndup(name, namesz);
@@ -957,7 +962,8 @@ int mnt_optlist_strdup_optstr(struct libmnt_optlist *ls, char **optstr,
                        continue;
                rc = mnt_buffer_append_option(&buf,
                                        opt->name, strlen(opt->name),
-                                       opt->value,
+                                       opt->value ? opt->value :
+                                                    opt->sepnodata ? "" : NULL,
                                        opt->value ? strlen(opt->value) : 0,
                                        opt->quoted);
                if (rc)
@@ -1043,6 +1049,7 @@ struct libmnt_optlist *mnt_copy_optlist(struct libmnt_optlist *ls)
                        no->src = opt->src;
                        no->external = opt->external;
                        no->quoted = opt->quoted;
+                       no->sepnodata = opt->sepnodata;
                }
        }
 
@@ -1184,6 +1191,11 @@ int mnt_opt_is_external(struct libmnt_opt *opt)
        return opt && opt->external ? 1 : 0;
 }
 
+int mnt_opt_is_sepnodata(struct libmnt_opt *opt)
+{
+       return opt->sepnodata;
+}
+
 
 #ifdef TEST_PROGRAM