From b77be9f072d5ee7cfaa80d385f714d4f1b0caea0 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Wed, 3 Jun 2026 13:54:13 +0000 Subject: [PATCH] fstab-generator: clear nosuid/nodev/noexec for root=bind: mounts A bind mount inherits the mount flags of the file system the source directory resides on. For root=bind: the source typically lives below /run/ (e.g. a freshly unpacked tar image in /run/machines/), which is mounted nosuid,nodev, so those flags propagated to /sysroot and broke suid binaries (e.g. sudo) and device nodes on the booted system. Default bind root mounts to dev,suid,exec instead, unless the user overrides this via rootflags=. Fixes: https://github.com/systemd/systemd/issues/41352 Co-developed-by: Claude Opus 4.8 --- man/systemd-fstab-generator.xml | 7 ++++++- src/fstab-generator/fstab-generator.c | 20 +++++++++++++++++++ .../sysroot.mount | 1 + .../sysroot.mount | 1 + .../test-22-bind.expected/sysroot.mount | 12 +++++++++++ test/test-fstab-generator/test-22-bind.input | 1 + 6 files changed, 41 insertions(+), 1 deletion(-) create mode 120000 test/test-fstab-generator/test-22-bind.expected/initrd-root-fs.target.requires/sysroot.mount create mode 120000 test/test-fstab-generator/test-22-bind.expected/initrd-usr-fs.target.requires/sysroot.mount create mode 100644 test/test-fstab-generator/test-22-bind.expected/sysroot.mount create mode 100644 test/test-fstab-generator/test-22-bind.input diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml index 8e684b29863..606dd33068d 100644 --- a/man/systemd-fstab-generator.xml +++ b/man/systemd-fstab-generator.xml @@ -105,7 +105,12 @@ Use bind:… to bind mount another directory as operating system root filesystems (added in v258). Expects an absolute path name referencing an existing directory within the initrd's file - hierarchy to boot into. + hierarchy to boot into. Since the resulting root file system is supposed to behave like a regular OS + root, the bind mount is established with the , and + options (i.e. the , and + flags that would otherwise be inherited from the file system the source + directory resides on, such as /run/, are cleared), unless overridden via + rootflags=. Set to off to turn off mounting of a root file system. diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 2c23d285010..f24974be5c8 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -1240,6 +1240,26 @@ static int add_sysroot_mount(void) { if (!strextend_with_separator(&combined_options, ",", extra_opts)) return log_oom(); + /* A bind mount inherits the mount flags (nosuid, nodev, noexec, …) of the file system the source + * directory is located on. The source typically lives below /run/ (e.g. a freshly unpacked tar image + * in /run/machines/), which is mounted nosuid,nodev, and these flags would then propagate to our root + * file system, breaking suid binaries (e.g. sudo) and device nodes. Since this is supposed to become a + * regular OS root file system, default to dev,suid,exec instead, unless the user explicitly requested + * otherwise. */ + if (bind) { + static const char* const defaults[] = { + "suid", "suid\0" "nosuid\0", + "dev", "dev\0" "nodev\0", + "exec", "exec\0" "noexec\0", + NULL, + }; + + STRV_FOREACH_PAIR(add, test, defaults) + if (!fstab_test_option(combined_options, *test)) + if (!strextend_with_separator(&combined_options, ",", *add)) + return log_oom(); + } + log_debug("Found entry what=%s where=/sysroot type=%s opts=%s", what, strna(fstype), strempty(combined_options)); /* Only honor x-systemd.makefs and .validatefs here, others are not relevant in initrd/not used diff --git a/test/test-fstab-generator/test-22-bind.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-22-bind.expected/initrd-root-fs.target.requires/sysroot.mount new file mode 120000 index 00000000000..0c969cdbd4a --- /dev/null +++ b/test/test-fstab-generator/test-22-bind.expected/initrd-root-fs.target.requires/sysroot.mount @@ -0,0 +1 @@ +../sysroot.mount \ No newline at end of file diff --git a/test/test-fstab-generator/test-22-bind.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-22-bind.expected/initrd-usr-fs.target.requires/sysroot.mount new file mode 120000 index 00000000000..0c969cdbd4a --- /dev/null +++ b/test/test-fstab-generator/test-22-bind.expected/initrd-usr-fs.target.requires/sysroot.mount @@ -0,0 +1 @@ +../sysroot.mount \ No newline at end of file diff --git a/test/test-fstab-generator/test-22-bind.expected/sysroot.mount b/test/test-fstab-generator/test-22-bind.expected/sysroot.mount new file mode 100644 index 00000000000..bcc56c61b50 --- /dev/null +++ b/test/test-fstab-generator/test-22-bind.expected/sysroot.mount @@ -0,0 +1,12 @@ +# Automatically generated by systemd-fstab-generator + +[Unit] +Documentation=man:fstab(5) man:systemd-fstab-generator(8) +SourcePath=/proc/cmdline +Before=initrd-root-fs.target +After=imports.target + +[Mount] +What=/run/machines/root +Where=/sysroot +Options=rw,bind,suid,dev,exec diff --git a/test/test-fstab-generator/test-22-bind.input b/test/test-fstab-generator/test-22-bind.input new file mode 100644 index 00000000000..3e90e366abb --- /dev/null +++ b/test/test-fstab-generator/test-22-bind.input @@ -0,0 +1 @@ +root=bind:/run/machines/root -- 2.47.3