]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ukify: enable --sbat for UKIs too
authorLuca Boccassi <bluca@debian.org>
Mon, 3 Jul 2023 17:33:07 +0000 (18:33 +0100)
committerLuca Boccassi <bluca@debian.org>
Wed, 5 Jul 2023 20:31:08 +0000 (21:31 +0100)
For confidential computing they want to be able to revoke initrds too, so allow
passing a specific --sbat section when building a UKI too, not just an addon.
Merge it with the stub and kernel sections.

man/ukify.xml
src/ukify/test/test_ukify.py
src/ukify/ukify.py

index 31e54c473a657a8a44cf13497e76d4417b335163..28103ea2d43b96861f05b10bf14edd17cf70a266 100644 (file)
           <varname>SignKernel=</varname>/<option>--sign-kernel</option> is true, and the binary has already
           been signed, the signature will be appended anyway.</para></listitem>
         </varlistentry>
+
+        <varlistentry>
+          <term><varname>SBAT=<replaceable>TEXT</replaceable>|<replaceable>@PATH</replaceable></varname></term>
+          <term><option>--sbat=<replaceable>TEXT</replaceable>|<replaceable>@PATH</replaceable></option></term>
+
+          <listitem><para>SBAT metadata associated with the UKI or addon. SBAT policies are useful to revoke
+          whole groups of UKIs or addons with a single, static policy update that does not take space in
+          DBX/MOKX. If not specified manually, a default metadata entry consisting of
+          <literal>uki,1,UKI,uki,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html</literal>
+          will be used, to ensure it is always possible to revoke UKIs and addons. For more information on
+          SBAT see <ulink url="https://github.com/rhboot/shim/blob/main/SBAT.md">Shim's documentation.</ulink>
+          </para></listitem>
+        </varlistentry>
       </variablelist>
     </refsect2>
 
         </varlistentry>
       </variablelist>
     </refsect2>
-
-    <refsect2>
-      <title>[Addon:<replaceable>NAME</replaceable>] section</title>
-
-      <para>Currently, these options only apply when building PE addons.</para>
-
-      <variablelist>
-        <varlistentry>
-          <term><varname>SBAT=<replaceable>TEXT</replaceable>|<replaceable>@PATH</replaceable></varname></term>
-          <term><option>--sbat=<replaceable>TEXT</replaceable>|<replaceable>@PATH</replaceable></option></term>
-
-          <listitem><para>SBAT metadata associated with the addon. SBAT policies are useful to revoke whole
-          groups of addons with a single, static policy update that does not take space in DBX/MOKX. If not
-          specified manually, a default metadata entry consisting of
-          <literal>uki.addon.systemd,1,UKI Addon,uki.addon.systemd,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html</literal>
-          will be used, to ensure it is always possible to revoke addons. For more information on SBAT see
-          <ulink url="https://github.com/rhboot/shim/blob/main/SBAT.md">Shim's documentation.</ulink></para>
-          </listitem>
-        </varlistentry>
-      </variablelist>
-    </refsect2>
   </refsect1>
 
   <refsect1>
       --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
       --initrd=early_cpio \
       --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \
+      --sbat='sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
+      uki.author.myimage,1,UKI for System,uki.author.myimage,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html' \
       --pcr-private-key=pcr-private-initrd-key.pem \
       --pcr-public-key=pcr-public-initrd-key.pem \
       --phases='enter-initrd' \
index a6778bb694da77b417168a26d15f9ddb3c161bad..f79a13a36f858db27cb74db6f1f0b368e9a7c634 100755 (executable)
@@ -454,7 +454,14 @@ def test_addon(tmpdir):
         'build',
         f'--output={output}',
         '--cmdline=ARG1 ARG2 ARG3',
+        """--sbat=sbat,1,foo
+foo,1
+bar,2
+""",
         '--section=.test:CONTENTZ',
+        """--sbat=sbat,1,foo
+baz,3
+"""
     ]
     if stub := os.getenv('EFI_ADDON'):
         args += [f'--stub={stub}']
@@ -473,9 +480,21 @@ def test_addon(tmpdir):
     # let's check that objdump likes the resulting file
     dump = subprocess.check_output(['objdump', '-h', output], text=True)
 
-    for sect in 'text cmdline test'.split():
+    for sect in 'text cmdline test sbat'.split():
         assert re.search(fr'^\s*\d+\s+.{sect}\s+0', dump, re.MULTILINE)
 
+    pe = pefile.PE(output, fast_load=True)
+    found = False
+
+    for section in pe.sections:
+        if section.Name.rstrip(b"\x00").decode() == ".sbat":
+            assert found is False
+            split = section.get_data().rstrip(b"\x00").decode().splitlines()
+            assert split == ["sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md", "foo,1", "bar,2", "baz,3"]
+            found = True
+
+    assert found is True
+
 
 def unbase64(filename):
     tmp = tempfile.NamedTemporaryFile()
index de356d993cb0b858223c8509a2409399200908bf..e9d53c55272f280fc86a698ec88089b69a600937 100755 (executable)
@@ -601,10 +601,10 @@ def pe_add_sections(uki: UKI, output: str):
 
     pe.write(output)
 
-def merge_sbat(input: [pathlib.Path]) -> str:
+def merge_sbat(input_pe: [pathlib.Path], input_text: [str]) -> str:
     sbat = []
 
-    for f in input:
+    for f in input_pe:
         try:
             pe = pefile.PE(f, fast_load=True)
         except pefile.PEFormatError:
@@ -621,6 +621,15 @@ def merge_sbat(input: [pathlib.Path]) -> str:
                 # needs to be first.
                 sbat += split[1:]
 
+    for t in input_text:
+        if t.startswith('@'):
+            t = pathlib.Path(t[1:]).read_text()
+        split = t.splitlines()
+        if not split[0].startswith('sbat,'):
+            print(f"{t} does not contain a valid SBAT section, skipping.")
+            continue
+        sbat += split[1:]
+
     return 'sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md\n' + '\n'.join(sbat) + "\n\x00"
 
 def signer_sign(cmd):
@@ -755,11 +764,15 @@ def make_uki(opts):
     # UKI or addon creation - addons don't use the stub so we add SBAT manually
 
     if linux is not None:
-        # Merge the .sbat sections from the stub and the kernel, so that revocation can be done on either.
-        uki.add_section(Section.create('.sbat', merge_sbat([opts.stub, linux]), measure=False))
+        # Merge the .sbat sections from stub, kernel and parameter, so that revocation can be done on either.
+        uki.add_section(Section.create('.sbat', merge_sbat([opts.stub, linux], opts.sbat), measure=False))
         uki.add_section(Section.create('.linux', linux, measure=True))
-    elif opts.sbat:
-        uki.add_section(Section.create('.sbat', opts.sbat, measure=False))
+    else:
+        if not opts.sbat:
+            opts.sbat = ["""sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
+uki,1,UKI,uki,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html
+"""]
+        uki.add_section(Section.create('.sbat', merge_sbat([], opts.sbat), measure=False))
 
     if sign_args_present:
         unsigned = tempfile.NamedTemporaryFile(prefix='uki')
@@ -1131,11 +1144,10 @@ CONFIG_ITEMS = [
     ConfigItem(
         '--sbat',
         metavar = 'TEXT|@PATH',
-        help = 'SBAT policy [.sbat section] for addons',
-        default = """sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
-uki.addon,1,UKI Addon,uki.addon,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html
-""",
-        config_key = 'Addon/SBAT',
+        help = 'SBAT policy [.sbat section]',
+        default = [],
+        action = 'append',
+        config_key = 'UKI/SBAT',
     ),
 
     ConfigItem(