]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
83c9c0a6c4899dcfaa63bead068ac8b298c90470
[thirdparty/kernel/stable-queue.git] /
1 From 6bae50f8e1cd2fd5df15329ffe40984eea2153e1 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Wed, 28 Oct 2020 10:41:02 -0500
4 Subject: tpm: efi: Don't create binary_bios_measurements file for an empty log
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 From: Tyler Hicks <tyhicks@linux.microsoft.com>
10
11 [ Upstream commit 8ffd778aff45be760292225049e0141255d4ad6e ]
12
13 Mimic the pre-existing ACPI and Device Tree event log behavior by not
14 creating the binary_bios_measurements file when the EFI TPM event log is
15 empty.
16
17 This fixes the following NULL pointer dereference that can occur when
18 reading /sys/kernel/security/tpm0/binary_bios_measurements after the
19 kernel received an empty event log from the firmware:
20
21 BUG: kernel NULL pointer dereference, address: 000000000000002c
22 #PF: supervisor read access in kernel mode
23 #PF: error_code(0x0000) - not-present page
24 PGD 0 P4D 0
25 Oops: 0000 [#1] SMP PTI
26 CPU: 2 PID: 3932 Comm: fwupdtpmevlog Not tainted 5.9.0-00003-g629990edad62 #17
27 Hardware name: LENOVO 20LCS03L00/20LCS03L00, BIOS N27ET38W (1.24 ) 11/28/2019
28 RIP: 0010:tpm2_bios_measurements_start+0x3a/0x550
29 Code: 54 53 48 83 ec 68 48 8b 57 70 48 8b 1e 65 48 8b 04 25 28 00 00 00 48 89 45 d0 31 c0 48 8b 82 c0 06 00 00 48 8b 8a c8 06 00 00 <44> 8b 60 1c 48 89 4d a0 4c 89 e2 49 83 c4 20 48 83 fb 00 75 2a 49
30 RSP: 0018:ffffa9c901203db0 EFLAGS: 00010246
31 RAX: 0000000000000010 RBX: 0000000000000000 RCX: 0000000000000010
32 RDX: ffff8ba1eb99c000 RSI: ffff8ba1e4ce8280 RDI: ffff8ba1e4ce8258
33 RBP: ffffa9c901203e40 R08: ffffa9c901203dd8 R09: ffff8ba1ec443300
34 R10: ffffa9c901203e50 R11: 0000000000000000 R12: ffff8ba1e4ce8280
35 R13: ffffa9c901203ef0 R14: ffffa9c901203ef0 R15: ffff8ba1e4ce8258
36 FS: 00007f6595460880(0000) GS:ffff8ba1ef880000(0000) knlGS:0000000000000000
37 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
38 CR2: 000000000000002c CR3: 00000007d8d18003 CR4: 00000000003706e0
39 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
40 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
41 Call Trace:
42 ? __kmalloc_node+0x113/0x320
43 ? kvmalloc_node+0x31/0x80
44 seq_read+0x94/0x420
45 vfs_read+0xa7/0x190
46 ksys_read+0xa7/0xe0
47 __x64_sys_read+0x1a/0x20
48 do_syscall_64+0x37/0x80
49 entry_SYSCALL_64_after_hwframe+0x44/0xa9
50
51 In this situation, the bios_event_log pointer in the tpm_bios_log struct
52 was not NULL but was equal to the ZERO_SIZE_PTR (0x10) value. This was
53 due to the following kmemdup() in tpm_read_log_efi():
54
55 int tpm_read_log_efi(struct tpm_chip *chip)
56 {
57 ...
58 /* malloc EventLog space */
59 log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
60 if (!log->bios_event_log) {
61 ret = -ENOMEM;
62 goto out;
63 }
64 ...
65 }
66
67 When log_size is zero, due to an empty event log from firmware,
68 ZERO_SIZE_PTR is returned from kmemdup(). Upon a read of the
69 binary_bios_measurements file, the tpm2_bios_measurements_start()
70 function does not perform a ZERO_OR_NULL_PTR() check on the
71 bios_event_log pointer before dereferencing it.
72
73 Rather than add a ZERO_OR_NULL_PTR() check in functions that make use of
74 the bios_event_log pointer, simply avoid creating the
75 binary_bios_measurements_file as is done in other event log retrieval
76 backends.
77
78 Explicitly ignore all of the events in the final event log when the main
79 event log is empty. The list of events in the final event log cannot be
80 accurately parsed without referring to the first event in the main event
81 log (the event log header) so the final event log is useless in such a
82 situation.
83
84 Fixes: 58cc1e4faf10 ("tpm: parse TPM event logs based on EFI table")
85 Link: https://lore.kernel.org/linux-integrity/E1FDCCCB-CA51-4AEE-AC83-9CDE995EAE52@canonical.com/
86 Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
87 Reported-by: Kenneth R. Crudup <kenny@panix.com>
88 Reported-by: Mimi Zohar <zohar@linux.ibm.com>
89 Cc: ThiƩbaud Weksteen <tweek@google.com>
90 Cc: Ard Biesheuvel <ardb@kernel.org>
91 Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
92 Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
93 Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
94 Signed-off-by: Sasha Levin <sashal@kernel.org>
95 ---
96 drivers/char/tpm/eventlog/efi.c | 5 +++++
97 1 file changed, 5 insertions(+)
98
99 diff --git a/drivers/char/tpm/eventlog/efi.c b/drivers/char/tpm/eventlog/efi.c
100 index 6bb023de17f1f..35229e5143cac 100644
101 --- a/drivers/char/tpm/eventlog/efi.c
102 +++ b/drivers/char/tpm/eventlog/efi.c
103 @@ -41,6 +41,11 @@ int tpm_read_log_efi(struct tpm_chip *chip)
104 log_size = log_tbl->size;
105 memunmap(log_tbl);
106
107 + if (!log_size) {
108 + pr_warn("UEFI TPM log area empty\n");
109 + return -EIO;
110 + }
111 +
112 log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size,
113 MEMREMAP_WB);
114 if (!log_tbl) {
115 --
116 2.27.0
117