Skip to content

Commit

Permalink
Merge pull request #3103 from DaanDeMeyer/relax
Browse files Browse the repository at this point in the history
Relax read-only mounts even more
  • Loading branch information
DaanDeMeyer authored Oct 7, 2024
2 parents f9dc109 + b11b0f2 commit d46ce04
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 132 deletions.
124 changes: 71 additions & 53 deletions mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1511,15 +1511,15 @@ def run_ukify(
"build",
*arguments,
"--efi-arch", arch,
"--stub", stub,
"--stub", workdir(stub),
"--output", workdir(output),
*(["--cmdline", f"@{context.workspace / 'cmdline'}"] if cmdline else []),
*(["--cmdline", f"@{workdir(context.workspace / 'cmdline')}"] if cmdline else []),
] # fmt: skip

opt: list[PathString] = [
"--ro-bind", stub, stub,
"--ro-bind", stub, workdir(stub),
"--bind", output.parent, workdir(output.parent),
"--ro-bind", context.workspace / "cmdline", context.workspace / "cmdline",
"--ro-bind", context.workspace / "cmdline", workdir(context.workspace / "cmdline"),
] # fmt: skip

if sign and context.config.secure_boot:
Expand All @@ -1529,27 +1529,27 @@ def run_ukify(
if context.config.secure_boot_sign_tool != SecureBootSignTool.pesign:
cmd += [
"--signtool", "sbsign",
"--secureboot-private-key", context.config.secure_boot_key,
"--secureboot-certificate", context.config.secure_boot_certificate,
"--secureboot-certificate", workdir(context.config.secure_boot_certificate),
] # fmt: skip
opt += [
"--ro-bind", context.config.secure_boot_certificate, context.config.secure_boot_certificate,
"--ro-bind", context.config.secure_boot_certificate, workdir(context.config.secure_boot_certificate), # noqa
] # fmt: skip
if context.config.secure_boot_key_source.type == KeySourceType.engine:
cmd += ["--signing-engine", context.config.secure_boot_key_source.source]
opt += ["--bind-try", "/run/pcscd", "/run/pcscd"]
if context.config.secure_boot_key.exists():
opt += ["--ro-bind", context.config.secure_boot_key, context.config.secure_boot_key]
cmd += ["--secureboot-private-key", workdir(context.config.secure_boot_key)]
opt += ["--ro-bind", context.config.secure_boot_key, workdir(context.config.secure_boot_key)]
else:
cmd += ["--secureboot-private-key", context.config.secure_boot_key]
else:
pesign_prepare(context)
cmd += [
"--signtool", "pesign",
"--secureboot-certificate-dir",
context.workspace / "pesign",
"--secureboot-certificate-name",
certificate_common_name(context, context.config.secure_boot_certificate),
"--secureboot-certificate-dir", workdir(context.workspace / "pesign"),
"--secureboot-certificate-name", certificate_common_name(context, context.config.secure_boot_certificate), # noqa
] # fmt: skip
opt += ["--ro-bind", context.workspace / "pesign", context.workspace / "pesign"]
opt += ["--ro-bind", context.workspace / "pesign", workdir(context.workspace / "pesign")]

run(
cmd,
Expand All @@ -1576,17 +1576,16 @@ def build_uki(
die("Could not find ukify")

arguments: list[PathString] = [
"--os-release", f"@{context.root / 'usr/lib/os-release'}",
"--os-release", f"@{workdir(context.root / 'usr/lib/os-release')}",
"--uname", kver,
"--linux", kimg,
*flatten(["--join-profile", os.fspath(profile)] for profile in profiles),
"--linux", workdir(kimg),
*flatten(["--join-profile", os.fspath(workdir(profile))] for profile in profiles),
] # fmt: skip

options: list[PathString] = [
"--ro-bind", context.workspace / "cmdline", context.workspace / "cmdline",
"--ro-bind", context.root / "usr/lib/os-release", context.root / "usr/lib/os-release",
"--ro-bind", kimg, kimg,
*flatten(["--ro-bind", os.fspath(profile), os.fspath(profile)] for profile in profiles),
"--ro-bind", context.root / "usr/lib/os-release", workdir(context.root / "usr/lib/os-release"),
"--ro-bind", kimg, workdir(kimg),
*flatten(["--ro-bind", os.fspath(profile), os.fspath(workdir(profile))] for profile in profiles),
] # fmt: skip

if context.config.secure_boot:
Expand All @@ -1598,26 +1597,31 @@ def build_uki(
if want_signed_pcrs(context.config):
assert context.config.sign_expected_pcr_key
assert context.config.sign_expected_pcr_certificate

arguments += [
"--pcr-private-key", context.config.sign_expected_pcr_key,
# SHA1 might be disabled in OpenSSL depending on the distro so we opt to not sign
# for SHA1 to avoid having to manage a bunch of configuration to re-enable SHA1.
"--pcr-banks", "sha256",
] # fmt: skip
if context.config.sign_expected_pcr_key.exists():
options += ["--bind", context.config.sign_expected_pcr_key, context.config.sign_expected_pcr_key]

if context.config.sign_expected_pcr_key_source.type == KeySourceType.engine:
arguments += [
"--signing-engine", context.config.sign_expected_pcr_key_source.source,
"--pcr-public-key", context.config.sign_expected_pcr_certificate,
"--pcr-public-key", workdir(context.config.sign_expected_pcr_certificate),
] # fmt: skip
options += [
"--ro-bind",
context.config.sign_expected_pcr_certificate,
context.config.sign_expected_pcr_certificate,
"--ro-bind", context.config.sign_expected_pcr_certificate, workdir(context.config.sign_expected_pcr_certificate), # noqa
"--bind-try", "/run/pcscd", "/run/pcscd",
] # fmt: skip

if context.config.sign_expected_pcr_key.exists():
arguments += ["--pcr-private-key", workdir(context.config.sign_expected_pcr_key)]
options += [
"--ro-bind", context.config.sign_expected_pcr_key, workdir(context.config.sign_expected_pcr_key), # noqa
] # fmt: skip
else:
arguments += ["--pcr-private-key", context.config.sign_expected_pcr_key]

if microcodes:
# new .ucode section support?
if (
Expand All @@ -1631,14 +1635,14 @@ def build_uki(
and version >= "256"
):
for microcode in microcodes:
arguments += ["--microcode", microcode]
options += ["--ro-bind", microcode, microcode]
arguments += ["--microcode", workdir(microcode)]
options += ["--ro-bind", microcode, workdir(microcode)]
else:
initrds = microcodes + initrds

for initrd in initrds:
arguments += ["--initrd", initrd]
options += ["--ro-bind", initrd, initrd]
arguments += ["--initrd", workdir(initrd)]
options += ["--ro-bind", initrd, workdir(initrd)]

with complete_step(f"Generating unified kernel image for kernel version {kver}"):
run_ukify(context, stub, output, cmdline=" ".join(cmdline), arguments=arguments, options=options)
Expand Down Expand Up @@ -1980,8 +1984,8 @@ def install_pe_addons(context: Context) -> None:
context,
stub,
output,
arguments=["--config", addon],
options=["--ro-bind", addon, addon],
arguments=["--config", workdir(addon)],
options=["--ro-bind", addon, workdir(addon)],
)


Expand Down Expand Up @@ -2021,8 +2025,8 @@ def build_uki_profiles(context: Context, cmdline: Sequence[str]) -> list[Path]:
stub,
output,
cmdline=f"{' '.join(cmdline)} {profile_cmdline}",
arguments=["--config", profile],
options=["--ro-bind", profile, profile],
arguments=["--config", workdir(profile)],
options=["--ro-bind", profile, workdir(profile)],
sign=False,
)

Expand Down Expand Up @@ -2248,12 +2252,12 @@ def calculate_signature(context: Context) -> None:
if not home.exists():
die(f"GPG home {home} not found")

env = dict(GNUPGHOME=os.fspath(home))
env = dict(GNUPGHOME=os.fspath(workdir(home)))
if sys.stderr.isatty():
env |= dict(GPG_TTY=os.ttyname(sys.stderr.fileno()))

options: list[PathString] = [
"--bind", home, home,
"--bind", home, workdir(home),
"--bind", context.staging, workdir(context.staging),
"--bind", "/run", "/run",
] # fmt: skip
Expand Down Expand Up @@ -2880,13 +2884,13 @@ def have_cache(config: Config) -> bool:
logging.info("Cache manifest mismatch, not reusing cached images")
if ARG_DEBUG.get():
run(
["diff", "--unified", manifest, "-"],
["diff", "--unified", workdir(manifest), "-"],
input=new,
check=False,
sandbox=config.sandbox(
binary="diff",
tools=False,
options=["--bind", manifest, manifest],
options=["--bind", manifest, workdir(manifest)],
),
)

Expand Down Expand Up @@ -2999,7 +3003,7 @@ def make_image(
"--ro-bind",
context.config.verity_certificate,
workdir(context.config.verity_certificate),
]
] # noqa
if skip:
cmdline += ["--defer-partitions", ",".join(skip)]
if split:
Expand Down Expand Up @@ -3274,7 +3278,7 @@ def make_extension_image(context: Context, output: Path) -> None:
"--seed", str(context.config.seed) if context.config.seed else "random",
"--empty=create",
"--size=auto",
"--definitions", r,
"--definitions", workdir(r),
workdir(output),
] # fmt: skip
options: list[PathString] = [
Expand All @@ -3283,23 +3287,29 @@ def make_extension_image(context: Context, output: Path) -> None:
"--become-root",
"--bind", output.parent, workdir(output.parent),
"--ro-bind", context.root, "/buildroot",
"--ro-bind", r, r,
"--ro-bind", r, workdir(r),
] # fmt: skip

if not context.config.architecture.is_native():
cmdline += ["--architecture", str(context.config.architecture)]
if context.config.passphrase:
cmdline += ["--key-file", context.config.passphrase]
options += ["--ro-bind", context.config.passphrase, context.config.passphrase]
options += ["--ro-bind", context.config.passphrase, workdir(context.config.passphrase)]
if context.config.verity_key:
cmdline += ["--private-key", context.config.verity_key]
if context.config.verity_key_source.type != KeySourceType.file:
cmdline += ["--private-key-source", str(context.config.verity_key_source)]
if context.config.verity_key.exists():
options += ["--ro-bind", context.config.verity_key, context.config.verity_key]
cmdline += ["--private-key", workdir(context.config.verity_key)]
options += ["--ro-bind", context.config.verity_key, workdir(context.config.verity_key)]
else:
cmdline += ["--private-key", context.config.verity_key]
if context.config.verity_certificate:
cmdline += ["--certificate", context.config.verity_certificate]
options += ["--ro-bind", context.config.verity_certificate, context.config.verity_certificate]
cmdline += ["--certificate", workdir(context.config.verity_certificate)]
options += [
"--ro-bind",
context.config.verity_certificate,
workdir(context.config.verity_certificate),
] # noqa
if context.config.sector_size:
cmdline += ["--sector-size", str(context.config.sector_size)]
if context.config.split_artifacts:
Expand Down Expand Up @@ -3421,12 +3431,12 @@ def copy_repository_metadata(config: Config, dst: Path) -> None:
exclude: list[PathString]
if d == "cache":
exclude = flatten(
("--ro-bind", tmp, p)
("--ro-bind", tmp, workdir(p))
for p in config.distribution.package_manager(config).cache_subdirs(src)
)
else:
exclude = flatten(
("--ro-bind", tmp, p)
("--ro-bind", tmp, workdir(p))
for p in config.distribution.package_manager(config).state_subdirs(src)
)

Expand Down Expand Up @@ -3683,21 +3693,21 @@ def run_shell(args: Args, config: Config) -> None:
run(
[
"systemd-repart",
"--image", fname,
"--image", workdir(fname),
*([f"--size={config.runtime_size}"] if config.runtime_size else []),
"--no-pager",
"--dry-run=no",
"--offline=no",
"--pretty=no",
fname,
workdir(fname),
],
stdin=sys.stdin,
env=config.environment,
sandbox=config.sandbox(
binary="systemd-repart",
network=True,
devices=True,
options=["--bind", fname, fname],
options=["--bind", fname, workdir(fname)],
),
) # fmt: skip

Expand Down Expand Up @@ -4302,7 +4312,15 @@ def run_build(
if not Path(d).exists():
continue

if config.output_dir_or_cwd().is_relative_to(d):
if any(
p and p.is_relative_to(d)
for p in (
config.workspace_dir_or_default(),
config.package_cache_dir_or_default(),
config.cache_dir,
config.output_dir_or_cwd(),
)
):
continue

attrs = MOUNT_ATTR_RDONLY
Expand Down
26 changes: 18 additions & 8 deletions mkosi/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import Optional

from mkosi.log import log_step
from mkosi.run import SandboxProtocol, finalize_passwd_mounts, nosandbox, run
from mkosi.run import SandboxProtocol, finalize_passwd_mounts, nosandbox, run, workdir
from mkosi.sandbox import umask
from mkosi.types import PathString
from mkosi.util import chdir
Expand All @@ -32,7 +32,7 @@ def make_tar(src: Path, dst: Path, *, sandbox: SandboxProtocol = nosandbox) -> N
"tar",
"--create",
"--file", "-",
"--directory", src,
"--directory", workdir(src),
"--acls",
"--selinux",
# --xattrs implies --format=pax
Expand All @@ -49,7 +49,10 @@ def make_tar(src: Path, dst: Path, *, sandbox: SandboxProtocol = nosandbox) -> N
],
stdout=f,
# Make sure tar uses user/group information from the root directory instead of the host.
sandbox=sandbox(binary="tar", options=["--ro-bind", src, src, *finalize_passwd_mounts(src)]),
sandbox=sandbox(
binary="tar",
options=["--ro-bind", src, workdir(src), *finalize_passwd_mounts(src)],
),
) # fmt: skip


Expand All @@ -75,8 +78,8 @@ def extract_tar(
[
"tar",
"--extract",
"--file", src,
"--directory", dst,
"--file", workdir(src),
"--directory", workdir(dst),
"--keep-directory-symlink",
"--no-overwrite-dir",
"--same-permissions",
Expand All @@ -92,7 +95,11 @@ def extract_tar(
sandbox=sandbox(
binary="tar",
# Make sure tar uses user/group information from the root directory instead of the host.
options=["--ro-bind", src, src, "--bind", dst, dst, *finalize_passwd_mounts(dst)],
options=[
"--ro-bind", src, workdir(src),
"--bind", dst, workdir(dst),
*finalize_passwd_mounts(dst),
],
),
) # fmt: skip

Expand Down Expand Up @@ -122,10 +129,13 @@ def make_cpio(
"--null",
"--format=newc",
"--quiet",
"--directory", src,
"--directory", workdir(src),
*(["--owner=0:0"] if os.getuid() != 0 else []),
],
input="\0".join(os.fspath(f) for f in files),
stdout=f,
sandbox=sandbox(binary="cpio", options=["--ro-bind", src, src, *finalize_passwd_mounts(src)]),
sandbox=sandbox(
binary="cpio",
options=["--ro-bind", src, workdir(src), *finalize_passwd_mounts(src)],
),
) # fmt: skip
Loading

0 comments on commit d46ce04

Please sign in to comment.