summaryrefslogtreecommitdiff
path: root/src/ukify
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-12-20 10:38:01 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-12-20 16:10:36 +0100
commit095ff238d064f7dfbf75c9cd13834ed892fe5fd9 (patch)
treec6605e49da538c93d43c288f2bfa17b5a1abaaf0 /src/ukify
parent33bdec184f08d955979484d63bb60fba3942adca (diff)
downloadsystemd-095ff238d064f7dfbf75c9cd13834ed892fe5fd9.tar.gz
ukify: check early if inputs exist and are readable
It's much nicer for the user if we fail early instead of doing partial processing if we cannot read some input. We can't do those checks immediately from argparse.Parser.parse_args(), because we want to fully process the commandline first. In particular, even with invalid args, if --help is specified somewhere, we want to handle that. Thus, we need to delay the checks after argparse.Parser.parse_args() returns. Ukify didn't have type annotations on functions, but it probably should. Jörg's suggested correction included them and we might just as well start here.
Diffstat (limited to 'src/ukify')
-rwxr-xr-xsrc/ukify/ukify.py31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py
index cd27f92a97..0c4461c9a9 100755
--- a/src/ukify/ukify.py
+++ b/src/ukify/ukify.py
@@ -64,6 +64,15 @@ def shell_join(cmd):
return ' '.join(shlex.quote(str(x)) for x in cmd)
+def path_is_readable(s: str | None) -> pathlib.Path | None:
+ """Convert a filename string to a Path and verify access."""
+ if s is None:
+ return None
+ p = pathlib.Path(s)
+ p.open().close()
+ return p
+
+
def pe_executable_size(filename):
import pefile
@@ -675,26 +684,36 @@ usage: ukify [options…] linux initrd…
opts = p.parse_args(args)
+ path_is_readable(opts.linux)
+ for initrd in opts.initrd or ():
+ path_is_readable(initrd)
+ path_is_readable(opts.devicetree)
+ path_is_readable(opts.pcrpkey)
+ for key in opts.pcr_private_keys or ():
+ path_is_readable(key)
+ for key in opts.pcr_public_keys or ():
+ path_is_readable(key)
+
if opts.cmdline and opts.cmdline.startswith('@'):
- opts.cmdline = pathlib.Path(opts.cmdline[1:])
+ opts.cmdline = path_is_readable(opts.cmdline[1:])
if opts.os_release is not None and opts.os_release.startswith('@'):
- opts.os_release = pathlib.Path(opts.os_release[1:])
+ opts.os_release = path_is_readable(opts.os_release[1:])
elif opts.os_release is None:
p = pathlib.Path('/etc/os-release')
if not p.exists():
- p = pathlib.Path('/usr/lib/os-release')
+ p = path_is_readable('/usr/lib/os-release')
opts.os_release = p
if opts.efi_arch is None:
opts.efi_arch = guess_efi_arch()
if opts.stub is None:
- opts.stub = f'/usr/lib/systemd/boot/efi/linux{opts.efi_arch}.efi.stub'
+ opts.stub = path_is_readable(f'/usr/lib/systemd/boot/efi/linux{opts.efi_arch}.efi.stub')
if opts.signing_engine is None:
- opts.sb_key = pathlib.Path(opts.sb_key) if opts.sb_key else None
- opts.sb_cert = pathlib.Path(opts.sb_cert) if opts.sb_cert else None
+ opts.sb_key = path_is_readable(opts.sb_key) if opts.sb_key else None
+ opts.sb_cert = path_is_readable(opts.sb_cert) if opts.sb_cert else None
if bool(opts.sb_key) ^ bool(opts.sb_cert):
raise ValueError('--secureboot-private-key= and --secureboot-certificate= must be specified together')