mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
Merge pull request #28187 from bluca/sbat
ukify: merge .sbat sections from stub and kernel
This commit is contained in:
commit
cc5afe481e
@ -73,9 +73,10 @@
|
||||
<listitem><para>Pre-calculate the expected values seen in PCR register 11 after boot-up of a unified
|
||||
kernel image consisting of the components specified with <option>--linux=</option>,
|
||||
<option>--osrel=</option>, <option>--cmdline=</option>, <option>--initrd=</option>,
|
||||
<option>--splash=</option>, <option>--dtb=</option>, <option>--pcrpkey=</option> see below. Only
|
||||
<option>--linux=</option> is mandatory. (Alternatively, specify <option>--current</option> to use the
|
||||
current values of PCR register 11 instead.)</para></listitem>
|
||||
<option>--splash=</option>, <option>--dtb=</option>, <option>--sbat=</option>,
|
||||
<option>--pcrpkey=</option> see below. Only <option>--linux=</option> is mandatory. (Alternatively,
|
||||
specify <option>--current</option> to use the current values of PCR register 11 instead.)</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -112,6 +113,7 @@
|
||||
<term><option>--initrd=<replaceable>PATH</replaceable></option></term>
|
||||
<term><option>--splash=<replaceable>PATH</replaceable></option></term>
|
||||
<term><option>--dtb=<replaceable>PATH</replaceable></option></term>
|
||||
<term><option>--sbat=<replaceable>PATH</replaceable></option></term>
|
||||
<term><option>--pcrpkey=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
<listitem><para>When used with the <command>calculate</command> or <command>sign</command> verb,
|
||||
|
@ -98,6 +98,12 @@
|
||||
discussion of automatic enrollment in
|
||||
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
|
||||
</para>
|
||||
|
||||
<para>If the stub and/or the kernel contain <literal>.sbat</literal> sections they will be merged in
|
||||
the UKI so that revocation updates affecting either are considered when the UKI is loaded by Shim. For
|
||||
more information on SBAT see
|
||||
<ulink url="https://github.com/rhboot/shim/blob/main/SBAT.md">Shim's documentation.</ulink>
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
|
@ -85,6 +85,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" --splash=PATH Path to splash bitmap file %7$s .splash\n"
|
||||
" --dtb=PATH Path to Devicetree file %7$s .dtb\n"
|
||||
" --uname=PATH Path to 'uname -r' file %7$s .uname\n"
|
||||
" --sbat=PATH Path to SBAT file %7$s .sbat\n"
|
||||
" --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_invocation_short_name,
|
||||
@ -125,6 +126,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_SPLASH,
|
||||
ARG_DTB,
|
||||
ARG_UNAME,
|
||||
ARG_SBAT,
|
||||
_ARG_PCRSIG, /* the .pcrsig section is not input for signing, hence not actually an argument here */
|
||||
_ARG_SECTION_LAST,
|
||||
ARG_PCRPKEY = _ARG_SECTION_LAST,
|
||||
@ -148,6 +150,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "splash", required_argument, NULL, ARG_SPLASH },
|
||||
{ "dtb", required_argument, NULL, ARG_DTB },
|
||||
{ "uname", required_argument, NULL, ARG_UNAME },
|
||||
{ "sbat", required_argument, NULL, ARG_SBAT },
|
||||
{ "pcrpkey", required_argument, NULL, ARG_PCRPKEY },
|
||||
{ "current", no_argument, NULL, 'c' },
|
||||
{ "bank", required_argument, NULL, ARG_BANK },
|
||||
|
@ -12,6 +12,7 @@ const char* const unified_sections[_UNIFIED_SECTION_MAX + 1] = {
|
||||
[UNIFIED_SECTION_SPLASH] = ".splash",
|
||||
[UNIFIED_SECTION_DTB] = ".dtb",
|
||||
[UNIFIED_SECTION_UNAME] = ".uname",
|
||||
[UNIFIED_SECTION_SBAT] = ".sbat",
|
||||
[UNIFIED_SECTION_PCRSIG] = ".pcrsig",
|
||||
[UNIFIED_SECTION_PCRPKEY] = ".pcrpkey",
|
||||
NULL,
|
||||
|
@ -30,6 +30,7 @@ typedef enum UnifiedSection {
|
||||
UNIFIED_SECTION_SPLASH,
|
||||
UNIFIED_SECTION_DTB,
|
||||
UNIFIED_SECTION_UNAME,
|
||||
UNIFIED_SECTION_SBAT,
|
||||
UNIFIED_SECTION_PCRSIG,
|
||||
UNIFIED_SECTION_PCRPKEY,
|
||||
_UNIFIED_SECTION_MAX,
|
||||
|
@ -572,12 +572,26 @@ def pe_add_sections(uki: UKI, output: str):
|
||||
else:
|
||||
new_section.IMAGE_SCN_CNT_INITIALIZED_DATA = True
|
||||
|
||||
pe.__data__ = pe.__data__[:] + bytes(new_section.PointerToRawData - len(pe.__data__)) + data + bytes(new_section.SizeOfRawData - len(data))
|
||||
# Special case, mostly for .sbat: the stub will already have a .sbat section, but we want to append
|
||||
# the one from the kernel to it. It should be small enough to fit in the existing section, so just
|
||||
# swap the data.
|
||||
for i, s in enumerate(pe.sections):
|
||||
if s.Name.rstrip(b"\x00").decode() == section.name:
|
||||
if new_section.Misc_VirtualSize > s.SizeOfRawData:
|
||||
raise PEError(f'Not enough space in existing section {section.name} to append new data.')
|
||||
|
||||
pe.FILE_HEADER.NumberOfSections += 1
|
||||
pe.OPTIONAL_HEADER.SizeOfInitializedData += new_section.Misc_VirtualSize
|
||||
pe.__structures__.append(new_section)
|
||||
pe.sections.append(new_section)
|
||||
padding = bytes(new_section.SizeOfRawData - new_section.Misc_VirtualSize)
|
||||
pe.__data__ = pe.__data__[:s.PointerToRawData] + data + padding + pe.__data__[pe.sections[i+1].PointerToRawData:]
|
||||
s.SizeOfRawData = new_section.SizeOfRawData
|
||||
s.Misc_VirtualSize = new_section.Misc_VirtualSize
|
||||
break
|
||||
else:
|
||||
pe.__data__ = pe.__data__[:] + bytes(new_section.PointerToRawData - len(pe.__data__)) + data + bytes(new_section.SizeOfRawData - len(data))
|
||||
|
||||
pe.FILE_HEADER.NumberOfSections += 1
|
||||
pe.OPTIONAL_HEADER.SizeOfInitializedData += new_section.Misc_VirtualSize
|
||||
pe.__structures__.append(new_section)
|
||||
pe.sections.append(new_section)
|
||||
|
||||
pe.OPTIONAL_HEADER.CheckSum = 0
|
||||
pe.OPTIONAL_HEADER.SizeOfImage = round_up(
|
||||
@ -587,6 +601,28 @@ def pe_add_sections(uki: UKI, output: str):
|
||||
|
||||
pe.write(output)
|
||||
|
||||
def merge_sbat(input: [pathlib.Path]) -> str:
|
||||
sbat = []
|
||||
|
||||
for f in input:
|
||||
try:
|
||||
pe = pefile.PE(f, fast_load=True)
|
||||
except pefile.PEFormatError:
|
||||
print(f"{f} is not a valid PE file, not extracting SBAT section.")
|
||||
continue
|
||||
|
||||
for section in pe.sections:
|
||||
if section.Name.rstrip(b"\x00").decode() == ".sbat":
|
||||
split = section.get_data().rstrip(b"\x00").decode().splitlines()
|
||||
if not split[0].startswith('sbat,'):
|
||||
print(f"{f} does not contain a valid SBAT section, skipping.")
|
||||
continue
|
||||
# Filter out the sbat line, we'll add it back later, there needs to be only one and it
|
||||
# needs to be first.
|
||||
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):
|
||||
print('+', shell_join(cmd))
|
||||
subprocess.check_call(cmd)
|
||||
@ -719,6 +755,8 @@ 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))
|
||||
uki.add_section(Section.create('.linux', linux, measure=True))
|
||||
elif opts.sbat:
|
||||
uki.add_section(Section.create('.sbat', opts.sbat, measure=False))
|
||||
|
Loading…
Reference in New Issue
Block a user