From 6f2b2f4df0353a332fb122918a0d7733876c2f3f Mon Sep 17 00:00:00 2001 From: Jonghyun An Date: Mon, 5 Oct 2026 10:34:27 +0900 Subject: [PATCH] ukify: accept whitespace around commas in PCR bank and phase lists Splitting on either a comma or whitespace produces empty items when whitespace is adjacent to a comma. This rejects valid phase lists and leaves empty entries in PCR bank lists. Consume whitespace around commas and accept a single trailing comma in both lists. Reject leading commas, empty entries between commas and repeated trailing commas. Treat an empty PCR bank list as no banks. Update the existing configuration test to cover whitespace around commas and a trailing comma in both settings. (cherry picked from commit 44cf775de15c1853c28fd2610f49014855ba09ec) --- src/ukify/test/test_ukify.py | 12 ++++++++---- src/ukify/ukify.py | 11 +++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py index 36e597d491..f1f3dbfd36 100755 --- a/src/ukify/test/test_ukify.py +++ b/src/ukify/test/test_ukify.py @@ -115,7 +115,7 @@ def test_apply_config(tmp_path): Uname = 1.2.3 EFIArch=arm Stub = some/path4 - PCRBanks = sha512,sha1 + PCRBanks = sha512, sha1, SigningEngine = engine1 SecureBootPrivateKey = some/path5 SecureBootCertificate = some/path6 @@ -124,7 +124,7 @@ def test_apply_config(tmp_path): [PCRSignature:NAME] PCRPrivateKey = some/path7 PCRPublicKey = some/path8 - Phases = {':'.join(ukify.KNOWN_PHASES)} + Phases = enter-initrd, {':'.join(ukify.KNOWN_PHASES)}, ''' ) ) @@ -155,7 +155,9 @@ def test_apply_config(tmp_path): assert ns._groups == ['NAME'] assert ns.pcr_private_keys == ['some/path7'] assert ns.pcr_public_keys == ['some/path8'] - assert ns.phase_path_groups == [['enter-initrd:leave-initrd:sysinit:ready:shutdown:final']] + assert ns.phase_path_groups == [ + ['enter-initrd', 'enter-initrd:leave-initrd:sysinit:ready:shutdown:final'] + ] ukify.finalize_options(ns) @@ -180,7 +182,9 @@ def test_apply_config(tmp_path): assert ns._groups == ['NAME'] assert ns.pcr_private_keys == ['some/path7'] assert ns.pcr_public_keys == ['some/path8'] - assert ns.phase_path_groups == [['enter-initrd:leave-initrd:sysinit:ready:shutdown:final']] + assert ns.phase_path_groups == [ + ['enter-initrd', 'enter-initrd:leave-initrd:sysinit:ready:shutdown:final'] + ] def test_parse_args_minimal(): diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py index 6fc4f0de29..f6fa6d02fe 100755 --- a/src/ukify/ukify.py +++ b/src/ukify/ukify.py @@ -650,7 +650,13 @@ class SystemdSbSign(SignTool): def parse_banks(s: str) -> list[str]: - banks = re.split(r',|\s+', s) + s = s.strip() + if not s: + return [] + # Allow a single trailing comma, but reject any other empty entry. + banks = re.split(r'\s*,\s*|\s+', s.removesuffix(',').rstrip()) + if '' in banks: + raise argparse.ArgumentTypeError(f'Empty entry in PCR bank list {s!r}') # TODO: do some sanity checking here return banks @@ -667,7 +673,8 @@ KNOWN_PHASES = ( def parse_phase_paths(s: str) -> list[str]: # Split on commas or whitespace here. Commas might be hard to parse visually. - paths = re.split(r',|\s+', s) + # Allow a single trailing comma. Other empty entries are rejected below as unknown phases. + paths = re.split(r'\s*,\s*|\s+', s.strip().removesuffix(',').rstrip()) for path in paths: for phase in path.split(':'):