]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Mount over /etc/passwd again for virtiofsd
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 14 Dec 2023 21:43:25 +0000 (22:43 +0100)
committerJörg Behrmann <behrmann@physik.fu-berlin.de>
Fri, 15 Dec 2023 08:37:22 +0000 (09:37 +0100)
When running unprivileged with a tools tree and runtime trees we
still have to mount over /etc/passwd to keep things working.

mkosi/mounts.py
mkosi/qemu.py

index 191774ab411d072991029904b64a1b0640e2955f..dcac1f631fb60d36b1b616cf75c98a366dd9e032 100644 (file)
@@ -11,7 +11,7 @@ from typing import Optional
 
 from mkosi.run import run
 from mkosi.types import PathString
-from mkosi.util import umask
+from mkosi.util import INVOKING_USER, umask
 from mkosi.versioncomp import GenericVersion
 
 
@@ -148,3 +148,18 @@ def mount_usr(tree: Optional[Path], umount: bool = True) -> Iterator[None]:
             yield
     finally:
         os.environ["PATH"] = old
+
+
+@contextlib.contextmanager
+def mount_passwd() -> Iterator[None]:
+    with tempfile.NamedTemporaryFile(prefix="mkosi.passwd", mode="w") as passwd:
+        passwd.write("root:x:0:0:root:/root:/bin/sh\n")
+        if INVOKING_USER.uid != 0:
+            name = INVOKING_USER.name()
+            home = INVOKING_USER.home()
+            passwd.write(f"{name}:x:{INVOKING_USER.uid}:{INVOKING_USER.gid}:{name}:{home}:/bin/sh\n")
+        passwd.flush()
+        os.fchown(passwd.file.fileno(), INVOKING_USER.uid, INVOKING_USER.gid)
+
+        with mount(passwd.name, Path("/etc/passwd"), operation="--bind"):
+            yield
index d2e974f011fddfc057c87e5de63903ca5a5a29a0..b2e4ae93d53a1e21d49a83cd1aa1d3e8fe747e8c 100644 (file)
@@ -32,6 +32,7 @@ from mkosi.config import (
     format_bytes,
 )
 from mkosi.log import die
+from mkosi.mounts import mount_passwd
 from mkosi.partition import finalize_root, find_partitions
 from mkosi.run import (
     MkosiAsyncioThread,
@@ -592,6 +593,17 @@ def run_qemu(args: MkosiArgs, config: MkosiConfig, qemu_device_fds: Mapping[Qemu
     notifications: dict[str, str] = {}
 
     with contextlib.ExitStack() as stack:
+        if (
+            os.getuid() == 0 and
+            not INVOKING_USER.invoked_as_root and
+            config.runtime_trees
+        ):
+            # In this scenario newuidmap might fail when invoked by virtiofsd as the user running virtiofsd will not
+            # be resolvable to a name via NSS so we have to trick newuidmap by mounting over /etc/passwd. Once
+            # https://gitlab.com/virtio-fs/virtiofsd/-/issues/137 is fixed we can set up the user namespace ourselves
+            # without uidmap to avoid having to mount over /etc/passwd.
+            stack.enter_context(mount_passwd())
+
         for k, v in config.credentials.items():
             payload = base64.b64encode(v.encode()).decode()
             if config.architecture.supports_smbios() and firmware == QemuFirmware.uefi: