diff --git a/TODO.md b/TODO.md index 6e7cc16112..8c59952ad9 100644 --- a/TODO.md +++ b/TODO.md @@ -1212,12 +1212,6 @@ SPDX-License-Identifier: LGPL-2.1-or-later - in pid1: include ExecStart= cmdlines (and other Exec*= cmdlines) in polkit request, so that policies can match against command lines. -- in sd-boot and sd-stub measure the SMBIOS vendor strings to some PCR (at - least some subset of them that look like systemd stuff), because apparently - some firmware does not, but systemd honours it. avoid duplicate measurement - by sd-boot and sd-stub by adding LoaderFeatures/StubFeatures flag for this, - so that sd-stub can avoid it if sd-boot already did it. - - in sd-id128: also parse UUIDs in RFC4122 URN syntax (i.e. chop off urn:uuid: prefix) - in sd-stub: optionally add support for a new PE section .keyring or so that @@ -1745,8 +1739,6 @@ SPDX-License-Identifier: LGPL-2.1-or-later - measure all log-in attempts into a new nvpcr -- measure credentials picked up from SMBIOS to some suitable PCR - - measure GPT and LUKS headers somewhere when we use them (i.e. in systemd-gpt-auto-generator/systemd-repart and in systemd-cryptsetup?) diff --git a/docs/BOOT_LOADER_INTERFACE.md b/docs/BOOT_LOADER_INTERFACE.md index 36380f38f3..efe5c1cce2 100644 --- a/docs/BOOT_LOADER_INTERFACE.md +++ b/docs/BOOT_LOADER_INTERFACE.md @@ -145,6 +145,8 @@ Variables will be listed below using the Linux efivarfs naming, * `1 << 19` → The boot loader supports the `LoaderEntryPreferred` variable when set. * `1 << 20` → The boot loader reports the firmware-configured keyboard layout in the EFI variable `LoaderKeyboardLayout-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f`. + * `1 << 21` → The boot loader measures SMBIOS information into a TPM2 PCR and reports the PCR index in the + EFI variable `LoaderPcrSMBIOS-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f`. * The EFI variable `LoaderSystemToken-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f` contains binary random data, @@ -184,6 +186,17 @@ Variables will be listed below using the Linux efivarfs naming, uses this as a lowest-priority fallback keyboard layout when no explicit configuration is provided. +* The EFI variable `LoaderPcrSMBIOS-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f` + contains the index of the TPM2 PCR (as a decimal ASCII string formatted as a + NUL-terminated UTF-16 string, e.g. `1`) into which the boot loader measured + select SMBIOS structures: type 1 (system information, with the volatile + "Wake-up Type" field zeroed out), type 2 (baseboard information) and type 11 + (OEM strings). This is a volatile (non-persistent) variable, set only if a + measurement was successfully completed, and remains unset otherwise. Both + `systemd-boot` and `systemd-stub` perform this measurement; whichever runs + first sets the variable, and its presence suppresses a second measurement of + the same data into the same PCR during the same boot. + If `LoaderTimeInitUSec` and `LoaderTimeExecUSec` are set, `systemd-analyze` will include them in its boot-time analysis. If `LoaderDevicePartUUID` is set, systemd will mount the ESP that was used for the boot to `/boot`, but only if diff --git a/docs/TPM2_PCR_MEASUREMENTS.md b/docs/TPM2_PCR_MEASUREMENTS.md index 5d0801a907..8bdcd6979e 100644 --- a/docs/TPM2_PCR_MEASUREMENTS.md +++ b/docs/TPM2_PCR_MEASUREMENTS.md @@ -91,6 +91,45 @@ must be employed when designing a system that uses this feature. ## PCR Measurements Made by `systemd-boot` (UEFI) +### PCR 1, `EV_EVENT_TAG`, SMBIOS information + +Select SMBIOS structures provided by the firmware are measured into PCR 1 (the +TCG-defined register for platform configuration data), one tagged event per +structure: + +* SMBIOS type 1 (system information). The volatile "Wake-up Type" field is + zeroed before measuring, since it varies depending on how the machine was + powered on (cold boot, resume from sleep, AC restore, …) and would otherwise + make the measurement non-reproducible. +* SMBIOS type 2 (baseboard information). +* SMBIOS type 11 (OEM strings). There may be more than one such structure; all + are measured. + +Note that these measurements are – strictly speaking – redundant, since +firmwares are supposed to measure SMBIOS data anyway on their own. However, it +has been found this is not the case on many real-life implementations. Since in +particular SMBIOS type 11 may carry highly relevant input for the OS +(e.g. system credentials), an explicit measurement is made here to ensure all +parameters for the OS are comprehensively measured even on flaky firmwares. + +→ **Event Tag** `0xd5cb7cbc` for type 1, `0xe0d47bc8` for type 2, `0xc0b3bd23` +for type 11. + +→ **Description** in the event log record is `smbios:type1`, `smbios:type2` or +`smbios:type11` respectively, in UTF-16. + +→ **Measured hash** covers the raw bytes of the SMBIOS structure (formatted area +plus trailing string set), with the type 1 "Wake-up Type" field zeroed out as +described above. + +This measurement is also performed by `systemd-stub` (see below), so that systems +that boot a UKI directly, bypassing `systemd-boot`, still get it. Whichever +component runs first performs the measurement and sets the volatile +`LoaderPcrSMBIOS` EFI variable to the PCR index used; its presence suppresses a +second measurement of the same data into the same PCR during the same boot. Note +that the firmware itself typically also extends PCR 1, so its final value is not +solely determined by this measurement. + ### PCR 5, `EV_EVENT_TAG`, `loader.conf` The content of `systemd-boot`'s configuration file, `loader/loader.conf`, is @@ -120,6 +159,14 @@ trailing NUL bytes). ## PCR Measurements Made by `systemd-stub` (UEFI) +### PCR 1, `EV_EVENT_TAG`, SMBIOS information + +Identical to the SMBIOS measurement described above for `systemd-boot`. When +`systemd-stub` is invoked by `systemd-boot`, the measurement has typically already +been made (tracked via the `LoaderPcrSMBIOS` EFI variable) and is not repeated; +when the UKI is booted directly by the firmware, `systemd-stub` performs it +itself. + ### PCR 11, `EV_IPL`, PE section name A measurement is made for each PE section of the UKI that is defined by the diff --git a/man/systemd-boot.xml b/man/systemd-boot.xml index 1acf5d083e..2162c7ffb2 100644 --- a/man/systemd-boot.xml +++ b/man/systemd-boot.xml @@ -622,6 +622,19 @@ extra /6a9857a393724b7a981ebb5b8495b9ea/1.2.3/baz.confext.raw + + LoaderPcrSMBIOS + + The PCR register index select SMBIOS structures are measured into — type 1 + (system information, with the volatile "Wake-up Type" field zeroed out), type 2 (baseboard + information) and type 11 (OEM strings). Formatted as decimal ASCII string (e.g. + 1). Set by the boot loader if a measurement was successfully completed, and remains + unset otherwise. (Note that systemd-stub performs the same measurement when booted + directly, bypassing the boot loader.) + + + + LoaderImageIdentifier diff --git a/man/systemd-stub.xml b/man/systemd-stub.xml index 95f62ca66b..a5172fed1c 100644 --- a/man/systemd-stub.xml +++ b/man/systemd-stub.xml @@ -664,6 +664,20 @@ + + LoaderPcrSMBIOS + + The PCR register index select SMBIOS structures are measured into — type 1 + (system information, with the volatile "Wake-up Type" field zeroed out), type 2 (baseboard + information) and type 11 (OEM strings). Formatted as decimal ASCII string (e.g. + 1). This variable is set if a measurement was successfully completed, and remains + unset otherwise. systemd-stub performs this measurement only if it has not already + been done in the same boot (e.g. by the boot loader), as indicated by this variable being set + already. + + + + LoaderBootSecret diff --git a/src/boot/boot.c b/src/boot/boot.c index 9f833f02b1..3ba430a844 100644 --- a/src/boot/boot.c +++ b/src/boot/boot.c @@ -17,6 +17,7 @@ #include "iovec-util.h" #include "line-edit.h" #include "measure.h" +#include "measure-smbios.h" #include "memory-util.h" #include "part-discovery.h" #include "pe.h" @@ -3267,6 +3268,7 @@ static void export_loader_variables( EFI_LOADER_FEATURE_TYPE1_UKI_URL | EFI_LOADER_FEATURE_TPM2_ACTIVE_PCR_BANKS | EFI_LOADER_FEATURE_KEYBOARD_LAYOUT | + EFI_LOADER_FEATURE_SMBIOS_MEASURED | 0; assert(loaded_image); @@ -3434,6 +3436,10 @@ static EFI_STATUS run(EFI_HANDLE image) { export_common_variables(loaded_image); export_loader_variables(loaded_image, init_usec); + /* Measure SMBIOS data into PCR 1. This is done early, and suppressed if sd-stub later runs in + * the same boot (and vice versa), via the LoaderPcrSMBIOS EFI variable. */ + measure_smbios(); + (void) load_drivers(image, loaded_image, root_dir); _cleanup_free_ char16_t *loaded_image_path = NULL; diff --git a/src/boot/measure-smbios.c b/src/boot/measure-smbios.c new file mode 100644 index 0000000000..2379f4de9e --- /dev/null +++ b/src/boot/measure-smbios.c @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "efi-efivars.h" +#include "efi-log.h" +#include "measure.h" +#include "measure-smbios.h" +#include "smbios.h" +#include "tpm2-pcr.h" +#include "util.h" + +static void measure_smbios_raw( + const void *p, + size_t size, + uint32_t event_id, + const char16_t *description, + bool *measured) { + + EFI_STATUS err; + bool m = false; + + assert(p); + assert(description); + assert(measured); + + err = tpm_log_tagged_event( + TPM2_PCR_PLATFORM_CONFIG, + POINTER_TO_PHYSICAL_ADDRESS(p), + size, + event_id, + description, + &m); + if (err != EFI_SUCCESS) + log_error_status(err, "Unable to measure SMBIOS structure (%ls), ignoring: %m", description); + + *measured = *measured || m; +} + +static void measure_smbios_type1(const SmbiosHeader *header, size_t size, bool *measured) { + assert(header); + assert(measured); + + /* The wake-up type field varies depending on how the machine was powered on (cold boot, resume + * from sleep, AC restore, …), which would make the measurement non-reproducible. Hence measure a + * copy with that field zeroed out. */ + + assert(size >= sizeof(SmbiosTableType1)); + + _cleanup_free_ SmbiosTableType1 *copy = xmemdup(header, size); + copy->wake_up_type = 0; + + measure_smbios_raw(copy, size, SMBIOS_TYPE1_EVENT_TAG_ID, u"smbios:type1", measured); +} + +static bool measure_smbios_object(const SmbiosHeader *header, size_t size, void *userdata) { + bool *measured = ASSERT_PTR(userdata); + + switch (header->type) { + + case 1: /* System Information */ + measure_smbios_type1(header, size, measured); + break; + + case 2: /* Baseboard Information */ + measure_smbios_raw(header, size, SMBIOS_TYPE2_EVENT_TAG_ID, u"smbios:type2", measured); + break; + + case 11: /* OEM Strings */ + measure_smbios_raw(header, size, SMBIOS_TYPE11_EVENT_TAG_ID, u"smbios:type11", measured); + break; + + default: + break; + } + + return true; /* Keep iterating: there may be more than one matching structure (e.g. type 11). */ +} + +void measure_smbios(void) { + bool measured = false; + + if (!tpm_present()) + return; + + /* If the measurement was already done this boot (e.g. by sd-boot before it chainloaded us), don't + * do it again — re-extending PCR 1 would invalidate the value. */ + if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderPcrSMBIOS", /* ret_data= */ NULL, /* ret_size= */ NULL) == EFI_SUCCESS) + return; + + /* Measure SMBIOS type 1 (system information), type 2 (baseboard information) and type 11 (OEM + * strings) into PCR 1, in a single pass over the SMBIOS table. */ + smbios_foreach(measure_smbios_object, &measured); + + /* If we measured something, tell the OS which PCR we used (and suppress a second pass). */ + if (measured) + (void) efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"LoaderPcrSMBIOS", TPM2_PCR_PLATFORM_CONFIG, /* flags= */ 0); +} diff --git a/src/boot/measure-smbios.h b/src/boot/measure-smbios.h new file mode 100644 index 0000000000..758b2c45b4 --- /dev/null +++ b/src/boot/measure-smbios.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +/* Measures SMBIOS type 1 (system information, with the volatile "Wake-up Type" field masked) and all + * type 11 (OEM strings) structures into PCR 1, and records the PCR index in the transient + * LoaderPcrSMBIOS EFI variable. Called by both sd-boot and sd-stub; the presence of LoaderPcrSMBIOS + * suppresses a redundant second measurement when both run during the same boot. */ +void measure_smbios(void); diff --git a/src/boot/meson.build b/src/boot/meson.build index 2dc9c64256..d2524145d0 100644 --- a/src/boot/meson.build +++ b/src/boot/meson.build @@ -323,6 +323,7 @@ libefi_sources = files( 'hii.c', 'initrd.c', 'measure.c', + 'measure-smbios.c', 'part-discovery.c', 'pe.c', 'random-seed.c', diff --git a/src/boot/smbios.c b/src/boot/smbios.c index 0bbcf30123..46e9817acc 100644 --- a/src/boot/smbios.c +++ b/src/boot/smbios.c @@ -39,12 +39,6 @@ typedef struct { uint64_t table_address; } _packed_ Smbios3EntryPoint; -typedef struct { - uint8_t type; - uint8_t length; - uint8_t handle[2]; -} _packed_ SmbiosHeader; - typedef struct { SmbiosHeader header; uint8_t vendor; @@ -56,18 +50,6 @@ typedef struct { uint8_t bios_characteristics_ext[2]; } _packed_ SmbiosTableType0; -typedef struct { - SmbiosHeader header; - uint8_t manufacturer; - uint8_t product_name; - uint8_t version; - uint8_t serial_number; - EFI_GUID uuid; - uint8_t wake_up_type; - uint8_t sku_number; - uint8_t family; -} _packed_ SmbiosTableType1; - typedef struct { SmbiosHeader header; uint8_t manufacturer; @@ -103,6 +85,44 @@ static const void* find_smbios_configuration_table(uint64_t *ret_size) { return NULL; } +/* Given 'p' pointing at a structure header with 'size' bytes left in the table from there onwards, + * returns a pointer just past the end of this structure (i.e. the start of the next one), accounting + * for the formatted area and the trailing string set (terminated by a double NUL byte). Returns NULL + * if the structure is malformed or runs past the end of the table. */ +static const uint8_t* smbios_structure_end(const uint8_t *p, uint64_t size) { + assert(p); + + if (size < sizeof(SmbiosHeader)) + return NULL; + + const SmbiosHeader *header = (const SmbiosHeader *) p; + if (size < header->length) + return NULL; + + /* Skip over formatted area. */ + const uint8_t *q = p + header->length; + size -= header->length; + + /* Special case: if there are no strings appended, we'll see two NUL bytes. */ + if (size >= 2 && q[0] == 0 && q[1] == 0) + return q + 2; + + /* Skip over a populated string table. */ + bool first = true; + for (;;) { + const uint8_t *e = memchr(q, 0, size); + if (!e) + return NULL; + + if (!first && e == q) /* Double NUL byte means we've reached the end of the string table. */ + return q + 1; + + size -= e + 1 - q; + q = e + 1; + first = false; + } +} + static const SmbiosHeader* get_smbios_table(uint8_t type, size_t min_size, uint64_t *ret_size_left) { uint64_t size; const uint8_t *p = find_smbios_configuration_table(&size); @@ -132,34 +152,12 @@ static const SmbiosHeader* get_smbios_table(uint8_t type, size_t min_size, uint6 return header; /* Yay! */ } - /* Skip over formatted area. */ - size -= header->length; - p += header->length; + const uint8_t *next = smbios_structure_end(p, size); + if (!next) + goto not_found; - /* Special case: if there are no strings appended, we'll see two NUL bytes, skip over them */ - if (size >= 2 && p[0] == 0 && p[1] == 0) { - size -= 2; - p += 2; - continue; - } - - /* Skip over a populated string table. */ - bool first = true; - for (;;) { - const uint8_t *e = memchr(p, 0, size); - if (!e) - goto not_found; - - if (!first && e == p) {/* Double NUL byte means we've reached the end of the string table. */ - p++; - size--; - break; - } - - size -= e + 1 - p; - p = e + 1; - first = false; - } + size -= next - p; + p = next; } not_found: @@ -169,6 +167,40 @@ not_found: return NULL; } +void smbios_foreach(SmbiosForeachFunc func, void *userdata) { + assert(func); + + uint64_t size; + const uint8_t *p = find_smbios_configuration_table(&size); + if (!p) + return; + + /* Walks the SMBIOS table exactly once, invoking 'func' for every structure. 'func' receives the + * structure's header (which carries its type) and the structure's total length (formatted area + + * trailing string set); returning false stops the iteration early. */ + + for (;;) { + if (size < sizeof(SmbiosHeader)) + return; + + const SmbiosHeader *header = (const SmbiosHeader *) p; + + /* End of table. */ + if (header->type == 127) + return; + + const uint8_t *next = smbios_structure_end(p, size); + if (!next) + return; + + if (!func(header, next - p, userdata)) + return; + + size -= next - p; + p = next; + } +} + bool smbios_in_hypervisor(void) { /* Look up BIOS Information (Type 0). */ const SmbiosTableType0 *type0 = (const SmbiosTableType0 *) get_smbios_table(0, sizeof(SmbiosTableType0), /* ret_size_left= */ NULL); diff --git a/src/boot/smbios.h b/src/boot/smbios.h index 694ef568e6..226ebf758f 100644 --- a/src/boot/smbios.h +++ b/src/boot/smbios.h @@ -3,10 +3,35 @@ #include "efi.h" +typedef struct { + uint8_t type; + uint8_t length; + uint8_t handle[2]; +} _packed_ SmbiosHeader; + +typedef struct { + SmbiosHeader header; + uint8_t manufacturer; + uint8_t product_name; + uint8_t version; + uint8_t serial_number; + EFI_GUID uuid; + uint8_t wake_up_type; + uint8_t sku_number; + uint8_t family; +} _packed_ SmbiosTableType1; + bool smbios_in_hypervisor(void); const char* smbios_find_oem_string(const char *name, const char *after); +/* Invoked by smbios_foreach() for each SMBIOS structure. 'header' points at the structure (which + * carries its type), and 'size' is the structure's total length (formatted area + trailing string + * set). Returning false stops the iteration. */ +typedef bool (*SmbiosForeachFunc)(const SmbiosHeader *header, size_t size, void *userdata); + +void smbios_foreach(SmbiosForeachFunc func, void *userdata); + typedef struct RawSmbiosInfo { const char *manufacturer; const char *product_name; diff --git a/src/boot/stub.c b/src/boot/stub.c index 6411102ec4..712a82e739 100644 --- a/src/boot/stub.c +++ b/src/boot/stub.c @@ -14,6 +14,7 @@ #include "iovec-util.h" #include "linux.h" #include "measure.h" +#include "measure-smbios.h" #include "memory-util.h" #include "part-discovery.h" #include "pe.h" @@ -116,6 +117,7 @@ static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, unsig EFI_STUB_FEATURE_MULTI_PROFILE_UKI | /* We grok the "@1" profile command line argument */ EFI_STUB_FEATURE_REPORT_STUB_PARTITION | /* We set StubDevicePartUUID + StubImageIdentifier */ EFI_STUB_FEATURE_REPORT_URL | /* We set StubDeviceURL + LoaderDeviceURL */ + EFI_STUB_FEATURE_SMBIOS_MEASURED | /* We measure SMBIOS data into PCR 1 */ 0; assert(loaded_image); @@ -1252,6 +1254,10 @@ static EFI_STATUS run(EFI_HANDLE image) { export_common_variables(loaded_image); export_stub_variables(loaded_image, profile); + /* Measure SMBIOS data into PCR 1, unless sd-boot already did so in the same boot (tracked via + * the LoaderPcrSMBIOS EFI variable). */ + measure_smbios(); + /* First load the base device tree, then fix it up using addons - global first, then per-UKI. */ install_embedded_devicetree(loaded_image, sections, &dt_state); install_addon_devicetrees(&dt_state, dt_addons, n_dt_addons, ¶meters_measured); diff --git a/src/bootctl/bootctl-status.c b/src/bootctl/bootctl-status.c index 4aac25a74d..f1c75c4a65 100644 --- a/src/bootctl/bootctl-status.c +++ b/src/bootctl/bootctl-status.c @@ -408,6 +408,7 @@ int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) { { EFI_LOADER_FEATURE_TYPE1_UKI_URL, "Support Type #1 uki-url field" }, { EFI_LOADER_FEATURE_TPM2_ACTIVE_PCR_BANKS, "Loader reports active TPM2 PCR banks" }, { EFI_LOADER_FEATURE_KEYBOARD_LAYOUT, "Loader reports firmware keyboard layout" }, + { EFI_LOADER_FEATURE_SMBIOS_MEASURED, "Loader measures SMBIOS information" }, }; static const struct { uint64_t flag; @@ -425,6 +426,7 @@ int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) { { EFI_STUB_FEATURE_CMDLINE_SMBIOS, "Pick up .cmdline from SMBIOS Type 11" }, { EFI_STUB_FEATURE_DEVICETREE_ADDONS, "Pick up .dtb from addons" }, { EFI_STUB_FEATURE_MULTI_PROFILE_UKI, "Stub understands profile selector" }, + { EFI_STUB_FEATURE_SMBIOS_MEASURED, "Stub measures SMBIOS information" }, }; _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL, *stub_path = NULL, *current_entry = NULL, *oneshot_entry = NULL, *preferred_entry = NULL, *default_entry = NULL, *sysfail_entry = NULL, diff --git a/src/fundamental/efivars.h b/src/fundamental/efivars.h index eddda7c23a..88bc97d75d 100644 --- a/src/fundamental/efivars.h +++ b/src/fundamental/efivars.h @@ -30,6 +30,7 @@ #define EFI_LOADER_FEATURE_TPM2_ACTIVE_PCR_BANKS (UINT64_C(1) << 18) #define EFI_LOADER_FEATURE_ENTRY_PREFERRED (UINT64_C(1) << 19) #define EFI_LOADER_FEATURE_KEYBOARD_LAYOUT (UINT64_C(1) << 20) +#define EFI_LOADER_FEATURE_SMBIOS_MEASURED (UINT64_C(1) << 21) /* Features of the stub, i.e. systemd-stub */ #define EFI_STUB_FEATURE_REPORT_BOOT_PARTITION (UINT64_C(1) << 0) @@ -44,6 +45,7 @@ #define EFI_STUB_FEATURE_MULTI_PROFILE_UKI (UINT64_C(1) << 9) #define EFI_STUB_FEATURE_REPORT_STUB_PARTITION (UINT64_C(1) << 10) #define EFI_STUB_FEATURE_REPORT_URL (UINT64_C(1) << 11) +#define EFI_STUB_FEATURE_SMBIOS_MEASURED (UINT64_C(1) << 12) typedef enum SecureBootMode { SECURE_BOOT_UNSUPPORTED, diff --git a/src/fundamental/tpm2-pcr.h b/src/fundamental/tpm2-pcr.h index 1d39ba5959..72835e886b 100644 --- a/src/fundamental/tpm2-pcr.h +++ b/src/fundamental/tpm2-pcr.h @@ -56,3 +56,12 @@ enum { /* The tag used for EV_EVENT_TAG event log records covering the selected UKI profile */ #define UKI_PROFILE_EVENT_TAG_ID UINT32_C(0x13aed6db) + +/* The tag used for EV_EVENT_TAG event log records covering the SMBIOS type 1 (system information) structure */ +#define SMBIOS_TYPE1_EVENT_TAG_ID UINT32_C(0xd5cb7cbc) + +/* The tag used for EV_EVENT_TAG event log records covering the SMBIOS type 2 (baseboard information) structure */ +#define SMBIOS_TYPE2_EVENT_TAG_ID UINT32_C(0xe0d47bc8) + +/* The tag used for EV_EVENT_TAG event log records covering SMBIOS type 11 (OEM strings) structures */ +#define SMBIOS_TYPE11_EVENT_TAG_ID UINT32_C(0xc0b3bd23) diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index fa2ee54c57..a0d415209c 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -8,6 +8,7 @@ #include "sd-varlink.h" #include "alloc-util.h" +#include "ansi-color.h" #include "ask-password-api.h" #include "bitfield.h" #include "blockdev-util.h" @@ -29,7 +30,9 @@ #include "format-table.h" #include "format-util.h" #include "fs-util.h" +#include "glyph-util.h" #include "gpt.h" +#include "help-util.h" #include "hexdecoct.h" #include "initrd-util.h" #include "json-util.h" @@ -45,7 +48,6 @@ #include "pcrextend-util.h" #include "pcrlock-firmware.h" #include "pe-binary.h" -#include "pretty-print.h" #include "proc-cmdline.h" #include "recovery-key.h" #include "sort-util.h" @@ -744,6 +746,23 @@ static int event_log_record_extract_firmware_description(EventLogRecord *rec) { break; } + /* SMBIOS structures measured by sd-boot/sd-stub. The tagged event payload is just a + * constant identifying string ("smbios:typeN"), hence don't show it. */ + case SMBIOS_TYPE1_EVENT_TAG_ID: + if (!strextend_with_separator(&rec->description, ", ", "systemd: SMBIOS system information (type 1)")) + return log_oom(); + break; + + case SMBIOS_TYPE2_EVENT_TAG_ID: + if (!strextend_with_separator(&rec->description, ", ", "systemd: SMBIOS baseboard information (type 2)")) + return log_oom(); + break; + + case SMBIOS_TYPE11_EVENT_TAG_ID: + if (!strextend_with_separator(&rec->description, ", ", "systemd: SMBIOS OEM strings (type 11)")) + return log_oom(); + break; + default: { _cleanup_free_ char *s = NULL; @@ -5132,14 +5151,9 @@ static int verb_lock_raw(int argc, char *argv[], uintptr_t _data, void *userdata } static int help(void) { - _cleanup_free_ char *link = NULL; _cleanup_(table_unrefp) Table *commands = NULL, *protections = NULL, *options = NULL; int r; - r = terminal_urlify_man("systemd-pcrlock", "8", &link); - if (r < 0) - return log_oom(); - r = verbs_get_help_table(&commands); if (r < 0) return r; @@ -5154,28 +5168,25 @@ static int help(void) { (void) table_sync_column_widths(0, commands, protections, options); - printf("%s [OPTIONS...] COMMAND ...\n" - "\n%sManage a TPM2 PCR lock.%s\n", - program_invocation_short_name, - ansi_highlight(), - ansi_normal()); + help_cmdline("[OPTIONS...] COMMAND ..."); + help_abstract("Manage a TPM2 PCR lock."); - printf("\n%sCommands:%s\n", ansi_underline(), ansi_normal()); + help_section("Commands"); r = table_print_or_warn(commands); if (r < 0) return r; - printf("\n%sProtections:%s\n", ansi_underline(), ansi_normal()); + help_section("Protections"); r = table_print_or_warn(protections); if (r < 0) return r; - printf("\n%sOptions:%s\n", ansi_underline(), ansi_normal()); + help_section("Options"); r = table_print_or_warn(options); if (r < 0) return r; - printf("\nSee the %s for details.\n", link); + help_man_page_reference("systemd-pcrlock", "8"); return 0; }