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 <noreply@anthropic.com>
This commit is contained in:
Daan De Meyer
2026-06-03 20:21:54 +01:00
committed by Luca Boccassi
parent c280a16ab7
commit b77be9f072
6 changed files with 41 additions and 1 deletions
+20
View File
@@ -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