forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/char/tpm/eventlog/efi.c
....@@ -1,14 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2017 Google
34 *
45 * Authors:
56 * Thiebaud Weksteen <tweek@google.com>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version
10
- * 2 of the License, or (at your option) any later version.
11
- *
127 */
138
149 #include <linux/efi.h>
....@@ -21,10 +16,14 @@
2116 int tpm_read_log_efi(struct tpm_chip *chip)
2217 {
2318
19
+ struct efi_tcg2_final_events_table *final_tbl = NULL;
20
+ int final_events_log_size = efi_tpm_final_log_size;
2421 struct linux_efi_tpm_eventlog *log_tbl;
2522 struct tpm_bios_log *log;
2623 u32 log_size;
2724 u8 tpm_log_version;
25
+ void *tmp;
26
+ int ret;
2827
2928 if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
3029 return -ENODEV;
....@@ -57,15 +56,69 @@
5756
5857 /* malloc EventLog space */
5958 log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
60
- if (!log->bios_event_log)
61
- goto err_memunmap;
59
+ if (!log->bios_event_log) {
60
+ ret = -ENOMEM;
61
+ goto out;
62
+ }
63
+
6264 log->bios_event_log_end = log->bios_event_log + log_size;
63
-
6465 tpm_log_version = log_tbl->version;
65
- memunmap(log_tbl);
66
- return tpm_log_version;
6766
68
-err_memunmap:
67
+ ret = tpm_log_version;
68
+
69
+ if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR ||
70
+ final_events_log_size == 0 ||
71
+ tpm_log_version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
72
+ goto out;
73
+
74
+ final_tbl = memremap(efi.tpm_final_log,
75
+ sizeof(*final_tbl) + final_events_log_size,
76
+ MEMREMAP_WB);
77
+ if (!final_tbl) {
78
+ pr_err("Could not map UEFI TPM final log\n");
79
+ kfree(log->bios_event_log);
80
+ ret = -ENOMEM;
81
+ goto out;
82
+ }
83
+
84
+ /*
85
+ * The 'final events log' size excludes the 'final events preboot log'
86
+ * at its beginning.
87
+ */
88
+ final_events_log_size -= log_tbl->final_events_preboot_size;
89
+
90
+ /*
91
+ * Allocate memory for the 'combined log' where we will append the
92
+ * 'final events log' to.
93
+ */
94
+ tmp = krealloc(log->bios_event_log,
95
+ log_size + final_events_log_size,
96
+ GFP_KERNEL);
97
+ if (!tmp) {
98
+ kfree(log->bios_event_log);
99
+ ret = -ENOMEM;
100
+ goto out;
101
+ }
102
+
103
+ log->bios_event_log = tmp;
104
+
105
+ /*
106
+ * Append any of the 'final events log' that didn't also end up in the
107
+ * 'main log'. Events can be logged in both if events are generated
108
+ * between GetEventLog() and ExitBootServices().
109
+ */
110
+ memcpy((void *)log->bios_event_log + log_size,
111
+ final_tbl->events + log_tbl->final_events_preboot_size,
112
+ final_events_log_size);
113
+ /*
114
+ * The size of the 'combined log' is the size of the 'main log' plus
115
+ * the size of the 'final events log'.
116
+ */
117
+ log->bios_event_log_end = log->bios_event_log +
118
+ log_size + final_events_log_size;
119
+
120
+out:
121
+ memunmap(final_tbl);
69122 memunmap(log_tbl);
70
- return -ENOMEM;
123
+ return ret;
71124 }