Skip to content

Commit

Permalink
sandbox: Make sure we use pacman keyring and crypto policies from too…
Browse files Browse the repository at this point in the history
…ls tree

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.
  • Loading branch information
DaanDeMeyer committed Dec 20, 2024
1 parent b5b5846 commit 3055d28
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
33 changes: 13 additions & 20 deletions mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -3780,7 +3773,7 @@ def run_sandbox(args: Args, config: Config) -> None:
devices=True,
network=True,
relaxed=True,
options=options,
options=["--same-dir", *mounts],
),
)

Expand Down
36 changes: 20 additions & 16 deletions mkosi/mounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]))

0 comments on commit 3055d28

Please sign in to comment.