]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add fsconfig() btrfs workaround
authorKarel Zak <kzak@redhat.com>
Thu, 16 Feb 2023 12:44:24 +0000 (13:44 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 16 Feb 2023 12:44:24 +0000 (13:44 +0100)
The new kernel mount API is not properly implemented in all FS
drivers. See strace output:

fsconfig(3, FSCONFIG_SET_STRING, "source", "/dev/sda", 0) = 0
fsconfig(3, FSCONFIG_SET_STRING, "context", "system_u:object_r:root_t:s0", 0) = 0
fsconfig(3, FSCONFIG_CMD_CREATE, NULL, NULL, 0) = -1 EINVAL (Invalid argument)

Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context.c
libmount/src/context_mount.c
libmount/src/hook_mount.c
libmount/src/mountP.h

index 972853b3fef95427e2a29c0f1080a1ade3bdd8ac..8db6b69500ce88c4dbf3069ed445634b28308bc5 100644 (file)
@@ -165,6 +165,7 @@ int mnt_reset_context(struct libmnt_context *cxt)
        cxt->mountdata = NULL;
        cxt->flags = MNT_FL_DEFAULT;
        cxt->noautofs = 1;
+       cxt->has_selinux_opt = 0;
 
        cxt->map_linux = mnt_get_builtin_optmap(MNT_LINUX_MAP);
        cxt->map_userspace = mnt_get_builtin_optmap(MNT_USERSPACE_MAP);
@@ -288,6 +289,7 @@ struct libmnt_context *mnt_copy_context(struct libmnt_context *o)
        n->table_fltrcb_data = o->table_fltrcb_data;
 
        n->noautofs = o->noautofs;
+       n->has_selinux_opt = o->has_selinux_opt;
 
        return n;
 failed:
index d81741ea5cce96a7722b9700890050bd29c72fe1..7491ec205b43586492f6a58a0cfc810654879854 100644 (file)
@@ -169,6 +169,9 @@ static int fix_optstr(struct libmnt_context *cxt)
                                        rc = mnt_opt_set_quoted_value(opt, raw);
                                if (raw)
                                        freecon(raw);
+
+                               /* temporary for broken fsconfig() syscall */
+                               cxt->has_selinux_opt = 1;
                        }
                        if (rc)
                                goto done;
index 09a1f3f32507baef63f47697ff54d375c464ac75..c60c3513b5dad11a670c1e9873b742bd238b5fd0 100644 (file)
@@ -120,7 +120,7 @@ static int configure_superblock(struct libmnt_context *cxt,
        struct libmnt_opt *opt;
        int rc;
 
-       DBG(HOOK, ul_debugobj(hs, " configure FS"));
+       DBG(HOOK, ul_debugobj(hs, " config FS"));
 
        ol = mnt_context_get_optlist(cxt);
        if (!ol)
@@ -150,6 +150,7 @@ static int configure_superblock(struct libmnt_context *cxt,
                        return -errno;
        }
 
+       DBG(HOOK, ul_debugobj(hs, " config done [rc=0]"));
        return 0;
 }
 
@@ -231,7 +232,7 @@ static int hook_create_mount(struct libmnt_context *cxt,
        if (!src)
                return -EINVAL;
 
-       DBG(HOOK, ul_debugobj(hs, "create FS instance"));
+       DBG(HOOK, ul_debugobj(hs, "init FS"));
 
        rc = fsconfig(api->fd_fs, FSCONFIG_SET_STRING, "source", src, 0);
        set_syscall_status(cxt, "fsconfig", rc == 0);
@@ -239,6 +240,7 @@ static int hook_create_mount(struct libmnt_context *cxt,
        if (!rc)
                rc = configure_superblock(cxt, hs, api->fd_fs);
        if (!rc) {
+               DBG(HOOK, ul_debugobj(hs, "create FS"));
                rc = fsconfig(api->fd_fs, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
                set_syscall_status(cxt, "fsconfig", rc == 0);
        }
@@ -551,6 +553,22 @@ static int hook_prepare(struct libmnt_context *cxt,
        assert(cxt);
        assert(hs == &hookset_mount);
 
+       /*
+        * The current kernel btrfs driver does not completely implement
+        * fsconfig() as it does not work with selinux stuff.
+        *
+        * Don't use the new mount API in this situation. Let's hope this issue
+        * is temporary.
+        */
+       {
+               const char *type = mnt_fs_get_fstype(cxt->fs);
+
+               if (type && strcmp(type, "btrfs") == 0 && cxt->has_selinux_opt) {
+                       DBG(HOOK, ul_debugobj(hs, "don't use new API (btrfs issue)"));
+                       return 0;
+               }
+       }
+
        DBG(HOOK, ul_debugobj(hs, "prepare mount"));
 
        ol = mnt_context_get_optlist(cxt);
index 0d341c65a6a9e9794cb2f7692ad3f0b27cdb9c61..80015f94c346d72d00a08712e4020ab5ca1d7bc2 100644 (file)
@@ -427,6 +427,7 @@ struct libmnt_context
 
        unsigned int    enabled_textdomain : 1; /* bindtextdomain() called */
        unsigned int    noautofs : 1;           /* ignore autofs mounts */
+       unsigned int    has_selinux_opt : 1;    /* temporary for broken fsconfig() syscall */
 
        struct list_head        hooksets_datas; /* global hooksets data */
        struct list_head        hooksets_hooks; /* global hooksets data */