summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-05-30 10:02:36 +0200
committerLennart Poettering <lennart@poettering.net>2024-05-30 10:13:39 +0200
commitaeaac9a2899a11194d6f808ba70cd48d1253b7a3 (patch)
tree3dcd5ad35d4b5074bde0bad0f52897fbd346f5da
parentMerge pull request #33079 from poettering/watchdog-no-disarm (diff)
downloadsystemd-aeaac9a2899a11194d6f808ba70cd48d1253b7a3.tar.xz
systemd-aeaac9a2899a11194d6f808ba70cd48d1253b7a3.zip
efi-api: check /sys/class/tpm/tpm0/tpm_version_major, too
If the ceck for the ACPI TPM2 table did not work we currently check if the EFI TPM table exists to check if the firmware supports TPM2. Specifically we check if /sys/kernel/security/tpm0/binary_bios_measurements exists. But that's not enough, since that also exists on TPM1.2 systems. Hence, let's also check /sys/class/tpm/tpm0/tpm_version_major which should exist under similar conditions and tells us the kernel's idea of the TPM version in use. I originally intended to read the signature of the /sys/kernel/security/tpm0/binary_bios_measurements contents for this, but this is not ideal since that file has tight access mode, and our TPM availability check would thus not work anymore if invoked unpriv. Follow-up for 4b3391158197e9158cc754e56bbeaf94e2fd8395 Fixes: #33077
Diffstat (limited to '')
-rw-r--r--src/shared/efi-api.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/shared/efi-api.c b/src/shared/efi-api.c
index eb84e16dae..3ca33efafb 100644
--- a/src/shared/efi-api.c
+++ b/src/shared/efi-api.c
@@ -7,6 +7,7 @@
#include "efi-api.h"
#include "efivars.h"
#include "fd-util.h"
+#include "fileio.h"
#include "sort-util.h"
#include "stat-util.h"
#include "stdio-util.h"
@@ -481,6 +482,7 @@ int efi_get_boot_options(uint16_t **ret_options) {
bool efi_has_tpm2(void) {
static int cache = -1;
+ int r;
/* Returns whether the system has a TPM2 chip which is known to the EFI firmware. */
@@ -488,30 +490,35 @@ bool efi_has_tpm2(void) {
return cache;
/* First, check if we are on an EFI boot at all. */
- if (!is_efi_boot()) {
- cache = 0;
- return cache;
- }
+ if (!is_efi_boot())
+ return (cache = false);
/* Then, check if the ACPI table "TPM2" exists, which is the TPM2 event log table, see:
* https://trustedcomputinggroup.org/wp-content/uploads/TCG_ACPIGeneralSpecification_v1.20_r8.pdf
- * This table exists whenever the firmware is hooked up to TPM2. */
- cache = access("/sys/firmware/acpi/tables/TPM2", F_OK) >= 0;
- if (cache)
- return cache;
-
+ * This table exists whenever the firmware knows ACPI and is hooked up to TPM2. */
+ if (access("/sys/firmware/acpi/tables/TPM2", F_OK) >= 0)
+ return (cache = true);
if (errno != ENOENT)
log_debug_errno(errno, "Unable to test whether /sys/firmware/acpi/tables/TPM2 exists, assuming it doesn't: %m");
/* As the last try, check if the EFI firmware provides the EFI_TCG2_FINAL_EVENTS_TABLE
* stored in EFI configuration table, see:
- * https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf
- */
- cache = access("/sys/kernel/security/tpm0/binary_bios_measurements", F_OK) >= 0;
- if (!cache && errno != ENOENT)
- log_debug_errno(errno, "Unable to test whether /sys/kernel/security/tpm0/binary_bios_measurements exists, assuming it doesn't: %m");
+ *
+ * https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf */
+ if (access("/sys/kernel/security/tpm0/binary_bios_measurements", F_OK) >= 0) {
+ _cleanup_free_ char *major = NULL;
+
+ /* The EFI table might exist for TPM 1.2 as well, hence let's check explicitly which TPM version we are looking at here. */
+ r = read_virtual_file("/sys/class/tpm/tpm0/tpm_version_major", SIZE_MAX, &major, /* ret_size= */ NULL);
+ if (r >= 0)
+ return (cache = streq(strstrip(major), "2"));
+
+ log_debug_errno(r, "Unable to read /sys/class/tpm/tpm0/tpm_version_major, assuming TPM does not qualify as TPM2: %m");
+
+ } else if (errno != ENOENT)
+ log_debug_errno(errno, "Unable to test whether /sys/kernel/security/tpm0/binary_bios_measurements exists, assuming it doesn't: %m");
- return cache;
+ return (cache = false);
}
#endif