| From 9df997d7d584124fc9e1b17e84f33edda21e9195 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 13 Sep 2024 19:19:51 -0400 |
| Subject: tpm: fix signed/unsigned bug when checking event logs |
| |
| From: Gregory Price <gourry@gourry.net> |
| |
| [ Upstream commit e6d654e9f5a97742cfe794b1c4bb5d3fb2d25e98 ] |
| |
| A prior bugfix that fixes a signed/unsigned error causes |
| another signed unsigned error. |
| |
| A situation where log_tbl->size is invalid can cause the |
| size passed to memblock_reserve to become negative. |
| |
| log_size from the main event log is an unsigned int, and |
| the code reduces to the following |
| |
| u64 value = (int)unsigned_value; |
| |
| This results in sign extension, and the value sent to |
| memblock_reserve becomes effectively negative. |
| |
| Fixes: be59d57f9806 ("efi/tpm: Fix sanity check of unsigned tbl_size being less than zero") |
| Signed-off-by: Gregory Price <gourry@gourry.net> |
| Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> |
| Signed-off-by: Ard Biesheuvel <ardb@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/firmware/efi/tpm.c | 17 +++++++++-------- |
| 1 file changed, 9 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c |
| index e8d69bd548f3f..9c3613e6af158 100644 |
| --- a/drivers/firmware/efi/tpm.c |
| +++ b/drivers/firmware/efi/tpm.c |
| @@ -40,7 +40,8 @@ int __init efi_tpm_eventlog_init(void) |
| { |
| struct linux_efi_tpm_eventlog *log_tbl; |
| struct efi_tcg2_final_events_table *final_tbl; |
| - int tbl_size; |
| + unsigned int tbl_size; |
| + int final_tbl_size; |
| int ret = 0; |
| |
| if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) { |
| @@ -80,26 +81,26 @@ int __init efi_tpm_eventlog_init(void) |
| goto out; |
| } |
| |
| - tbl_size = 0; |
| + final_tbl_size = 0; |
| if (final_tbl->nr_events != 0) { |
| void *events = (void *)efi.tpm_final_log |
| + sizeof(final_tbl->version) |
| + sizeof(final_tbl->nr_events); |
| |
| - tbl_size = tpm2_calc_event_log_size(events, |
| - final_tbl->nr_events, |
| - log_tbl->log); |
| + final_tbl_size = tpm2_calc_event_log_size(events, |
| + final_tbl->nr_events, |
| + log_tbl->log); |
| } |
| |
| - if (tbl_size < 0) { |
| + if (final_tbl_size < 0) { |
| pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n"); |
| ret = -EINVAL; |
| goto out_calc; |
| } |
| |
| memblock_reserve(efi.tpm_final_log, |
| - tbl_size + sizeof(*final_tbl)); |
| - efi_tpm_final_log_size = tbl_size; |
| + final_tbl_size + sizeof(*final_tbl)); |
| + efi_tpm_final_log_size = final_tbl_size; |
| |
| out_calc: |
| early_memunmap(final_tbl, sizeof(*final_tbl)); |
| -- |
| 2.43.0 |
| |