Skip to content

Commit b2046c3

Browse files
poetteringbluca
authored andcommitted
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 4b33911 Fixes: #33077 (cherry picked from commit aeaac9a)
1 parent b097677 commit b2046c3

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

src/shared/efi-api.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "efi-api.h"
88
#include "efivars.h"
99
#include "fd-util.h"
10+
#include "fileio.h"
1011
#include "sort-util.h"
1112
#include "stat-util.h"
1213
#include "stdio-util.h"
@@ -481,37 +482,43 @@ int efi_get_boot_options(uint16_t **ret_options) {
481482

482483
bool efi_has_tpm2(void) {
483484
static int cache = -1;
485+
int r;
484486

485487
/* Returns whether the system has a TPM2 chip which is known to the EFI firmware. */
486488

487489
if (cache >= 0)
488490
return cache;
489491

490492
/* First, check if we are on an EFI boot at all. */
491-
if (!is_efi_boot()) {
492-
cache = 0;
493-
return cache;
494-
}
493+
if (!is_efi_boot())
494+
return (cache = false);
495495

496496
/* Then, check if the ACPI table "TPM2" exists, which is the TPM2 event log table, see:
497497
* https://trustedcomputinggroup.org/wp-content/uploads/TCG_ACPIGeneralSpecification_v1.20_r8.pdf
498-
* This table exists whenever the firmware is hooked up to TPM2. */
499-
cache = access("/sys/firmware/acpi/tables/TPM2", F_OK) >= 0;
500-
if (cache)
501-
return cache;
502-
498+
* This table exists whenever the firmware knows ACPI and is hooked up to TPM2. */
499+
if (access("/sys/firmware/acpi/tables/TPM2", F_OK) >= 0)
500+
return (cache = true);
503501
if (errno != ENOENT)
504502
log_debug_errno(errno, "Unable to test whether /sys/firmware/acpi/tables/TPM2 exists, assuming it doesn't: %m");
505503

506504
/* As the last try, check if the EFI firmware provides the EFI_TCG2_FINAL_EVENTS_TABLE
507505
* stored in EFI configuration table, see:
508-
* https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf
509-
*/
510-
cache = access("/sys/kernel/security/tpm0/binary_bios_measurements", F_OK) >= 0;
511-
if (!cache && errno != ENOENT)
512-
log_debug_errno(errno, "Unable to test whether /sys/kernel/security/tpm0/binary_bios_measurements exists, assuming it doesn't: %m");
506+
*
507+
* https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf */
508+
if (access("/sys/kernel/security/tpm0/binary_bios_measurements", F_OK) >= 0) {
509+
_cleanup_free_ char *major = NULL;
510+
511+
/* The EFI table might exist for TPM 1.2 as well, hence let's check explicitly which TPM version we are looking at here. */
512+
r = read_virtual_file("/sys/class/tpm/tpm0/tpm_version_major", SIZE_MAX, &major, /* ret_size= */ NULL);
513+
if (r >= 0)
514+
return (cache = streq(strstrip(major), "2"));
515+
516+
log_debug_errno(r, "Unable to read /sys/class/tpm/tpm0/tpm_version_major, assuming TPM does not qualify as TPM2: %m");
517+
518+
} else if (errno != ENOENT)
519+
log_debug_errno(errno, "Unable to test whether /sys/kernel/security/tpm0/binary_bios_measurements exists, assuming it doesn't: %m");
513520

514-
return cache;
521+
return (cache = false);
515522
}
516523

517524
#endif

0 commit comments

Comments
 (0)