diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml index 8e684b2986..606dd33068 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 2c23d28501..f24974be5c 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 0000000000..0c969cdbd4 --- /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 0000000000..0c969cdbd4 --- /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 0000000000..bcc56c61b5 --- /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 0000000000..3e90e366ab --- /dev/null +++ b/test/test-fstab-generator/test-22-bind.input @@ -0,0 +1 @@ +root=bind:/run/machines/root