Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sandbox: Make sure we use pacman keyring and crypto policies from tools tree #3291

Merged
merged 3 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]))
Loading