]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
sandbox: Make sure we use pacman keyring and crypto policies from tools tree
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 20 Dec 2024 10:39:37 +0000 (11:39 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 20 Dec 2024 10:39:37 +0000 (11:39 +0100)
If ToolsTreeCertificates=yes, we still need to make sure we use the
crypto policies and pacman keyring from the tools tree if one is used.

mkosi/__init__.py
mkosi/mounts.py

index 9a86514fee3f76a2658c1354d911b9934bbd9324..6ca7c30f39d5e1c5fa1b69506ca8f0aa368cc0c6 100644 (file)
@@ -3750,25 +3750,18 @@ def build_image(context: Context) -> None:
 
 def run_sandbox(args: Args, config: Config) -> None:
     cmdline = args.cmdline or [os.getenv("SHELL", "bash")]
-    options: list[PathString] = ["--same-dir"]
-
-    # If we're not using tools tree certificates we don't have to do anything since the relaxed sandbox will
-    # already have /etc and /var from the host so we don't need to do anything extra.
-    if config.tools_tree_certificates:
-        mounts = finalize_crypto_mounts(config)
-
-        # Since we reuse almost every top level directory from the host except /usr, the crypto mountpoints
-        # have to exist already in these directories or we'll fail with a permission error. Let's check this
-        # early and show a better error and a suggestion on how users can fix this issue. We use slice
-        # notation to get every 3rd item from the mounts list which is the destination path.
-        for dst in mounts[2::3]:
-            if not Path(dst).exists():
-                die(
-                    f"Missing mountpoint {dst}",
-                    hint=f"Create an empty directory at {dst} using 'mkdir -p {dst}' as root and try again",
-                )
-
-        options += mounts
+    mounts = finalize_crypto_mounts(config, relaxed=True)
+
+    # Since we reuse almost every top level directory from the host except /usr, the crypto mountpoints
+    # have to exist already in these directories or we'll fail with a permission error. Let's check this
+    # early and show a better error and a suggestion on how users can fix this issue. We use slice
+    # notation to get every 3rd item from the mounts list which is the destination path.
+    for dst in mounts[2::3]:
+        if not Path(dst).exists():
+            die(
+                f"Missing mountpoint {dst}",
+                hint=f"Create an empty directory at {dst} using 'mkdir -p {dst}' as root and try again",
+            )
 
     run(
         cmdline,
@@ -3780,7 +3773,7 @@ def run_sandbox(args: Args, config: Config) -> None:
             devices=True,
             network=True,
             relaxed=True,
-            options=options,
+            options=["--same-dir", *mounts],
         ),
     )
 
index 09ea674b36a946b95a0c7bcad73debfd8ddb8b87..a04d7f4b9b16c25c29db5154002e28726c0171d0 100644 (file)
@@ -86,25 +86,29 @@ def finalize_source_mounts(config: Config, *, ephemeral: bool) -> Iterator[list[
         yield options
 
 
-def finalize_crypto_mounts(config: Config) -> list[PathString]:
+def finalize_crypto_mounts(config: Config, relaxed: bool = False) -> list[PathString]:
+    mounts = []
     root = config.tools() if config.tools_tree_certificates else Path("/")
 
-    mounts = [
-        (root / subdir, Path("/") / subdir)
-        for subdir in (
-            Path("etc/pki"),
-            Path("etc/ssl"),
-            Path("etc/ca-certificates"),
-            Path("var/lib/ca-certificates"),
-        )
-        if (root / subdir).exists() and any(p for p in (root / subdir).rglob("*") if not p.is_dir())
-    ]
+    if not relaxed or root != Path("/"):
+        mounts += [
+            (root / subdir, Path("/") / subdir)
+            for subdir in (
+                Path("etc/pki"),
+                Path("etc/ssl"),
+                Path("etc/ca-certificates"),
+                Path("var/lib/ca-certificates"),
+            )
+            if (root / subdir).exists() and any(p for p in (root / subdir).rglob("*") if not p.is_dir())
+        ]
 
-    # This contains the Arch Linux keyring, which isn't certificates so ToolsTreeCertificates= doesn't apply.
-    if (config.tools() / "etc/pacman.d/gnupg").exists():
-        mounts += [(config.tools() / "etc/pacman.d/gnupg", Path("/etc/pacman.d/gnupg"))]
+    if not relaxed or config.tools() != Path("/"):
+        # This contains the Arch Linux keyring, which isn't certificates so ToolsTreeCertificates= doesn't
+        # apply.
+        if (config.tools() / "etc/pacman.d/gnupg").exists():
+            mounts += [(config.tools() / "etc/pacman.d/gnupg", Path("/etc/pacman.d/gnupg"))]
 
-    if (config.tools() / "etc/crypto-policies").exists():
-        mounts += [(config.tools() / "etc/crypto-policies", Path("/etc/crypto-policies"))]
+        if (config.tools() / "etc/crypto-policies").exists():
+            mounts += [(config.tools() / "etc/crypto-policies", Path("/etc/crypto-policies"))]
 
     return flatten(("--ro-bind", src, target) for src, target in sorted(set(mounts), key=lambda s: s[1]))