From d8946038089ae058f342274b21ae7f478179f6fa Mon Sep 17 00:00:00 2001 From: jiangfangjie 00559066 Date: Mon, 15 Nov 2021 12:22:49 +0800 Subject: [PATCH] tpm2-Fix-issue-with-misaligned-address-when-marshall --- libtpms.spec | 3 +- ...ith-misaligned-address-when-marshall.patch | 155 ++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 tpm2-Fix-issue-with-misaligned-address-when-marshall.patch diff --git a/libtpms.spec b/libtpms.spec index 3fc31da..a7cdcf0 100644 --- a/libtpms.spec +++ b/libtpms.spec @@ -35,7 +35,8 @@ Patch5: tpm2-Introduce-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FI.patch Patch6: tpm2-Pass-SEED_COMPAT_LEVEL-to-CryptAdjustPrimeCandi.patch Patch7: tpm2-Activate-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX.patch Patch8: tpm2-Initialize-a-whole-OBJECT-before-using-it.patch -Patch9: tpm2-NVMarshal-Handle-index-orderly-RAM-without-0-si.patch +Patch9: tpm2-Fix-issue-with-misaligned-address-when-marshall.patch +Patch10: tpm2-NVMarshal-Handle-index-orderly-RAM-without-0-si.patch %if "%{crypto_subsystem}" == "openssl" BuildRequires: openssl-devel diff --git a/tpm2-Fix-issue-with-misaligned-address-when-marshall.patch b/tpm2-Fix-issue-with-misaligned-address-when-marshall.patch new file mode 100644 index 0000000..18b073a --- /dev/null +++ b/tpm2-Fix-issue-with-misaligned-address-when-marshall.patch @@ -0,0 +1,155 @@ +From 3aac390ce146b40117ad213c24504bb678f4daeb Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 23 Nov 2020 13:15:53 -0500 +Subject: [PATCH] tpm2: Fix issue with misaligned address when marshalling + NVRAM (UBSAN) + +UBSAN detects possibly misaligned address when reading out of the +TPM 2's NVRAM and when writing back into it. The NV_RAM_HEADER may +be unaligned like this: + +tests/test_tpm2_save_load_state_3.log:tpm2/Marshal.c:117:29: \ + runtime error: load of misaligned address 0x7ffcb53b3bca for type 'UINT32', which requires 4 byte alignment + +Signed-off-by: Stefan Berger +--- + src/tpm2/NVMarshal.c | 59 +++++++++++++++++++++++++++----------------- + 1 file changed, 36 insertions(+), 23 deletions(-) + +diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c +index ec94ebf..74ea17f 100644 +--- a/src/tpm2/NVMarshal.c ++++ b/src/tpm2/NVMarshal.c +@@ -3991,7 +3991,7 @@ INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size, + BYTE **buffer, INT32 *size) + { + UINT16 written; +- NV_RAM_HEADER *nrh; ++ NV_RAM_HEADER nrh, *nrhp; + UINT16 offset = 0; + UINT16 datasize; + UINT32 sourceside_size = array_size; +@@ -4005,36 +4005,42 @@ INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size, + written += UINT32_Marshal(&sourceside_size, buffer, size); + + while (TRUE) { +- nrh = array + offset; ++ nrhp = array + offset; ++ /* nrhp may point to misaligned address (ubsan), so use 'nrh'; first access only 'size' */ ++ memcpy(&nrh, nrhp, sizeof(nrh.size)); ++ + /* write the NVRAM header; + nrh->size holds the complete size including data; + nrh->size = 0 indicates the end */ +- written += UINT32_Marshal(&nrh->size, buffer, size); +- if (nrh->size == 0) ++ written += UINT32_Marshal(&nrh.size, buffer, size); ++ if (nrh.size == 0) + break; +- written += TPM_HANDLE_Marshal(&nrh->handle, buffer, size); +- written += TPMA_NV_Marshal(&nrh->attributes, buffer, size); ++ /* copy the entire structure now; ubsan does not allow 'nrh = *nrhp' */ ++ memcpy(&nrh, nrhp, sizeof(nrh)); ++ ++ written += TPM_HANDLE_Marshal(&nrh.handle, buffer, size); ++ written += TPMA_NV_Marshal(&nrh.attributes, buffer, size); + +- if (offset + nrh->size > array_size) { ++ if (offset + nrh.size > array_size) { + TPMLIB_LogTPM2Error("NV_ORDERLY_RAM: nrh->size corrupted: %d\n", +- nrh->size); ++ nrh.size); + break; + } + /* write data size before array */ +- if (nrh->size < sizeof(NV_RAM_HEADER)) { ++ if (nrh.size < sizeof(NV_RAM_HEADER)) { + TPMLIB_LogTPM2Error( + "NV_ORDERLY_RAM: nrh->size < sizeof(NV_RAM_HEADER): %d < %zu\n", +- (int)nrh->size, sizeof(NV_RAM_HEADER)); ++ (int)nrh.size, sizeof(NV_RAM_HEADER)); + break; + } +- datasize = nrh->size - sizeof(NV_RAM_HEADER); ++ datasize = nrh.size - sizeof(NV_RAM_HEADER); + written += UINT16_Marshal(&datasize, buffer, size); + if (datasize > 0) { + /* append the data */ + written += Array_Marshal(array + offset + sizeof(NV_RAM_HEADER), + datasize, buffer, size); + } +- offset += nrh->size; ++ offset += nrh.size; + } + + written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); +@@ -4053,7 +4059,7 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size, + { + TPM_RC rc = TPM_RC_SUCCESS; + NV_HEADER hdr; +- NV_RAM_HEADER *nrh; ++ NV_RAM_HEADER nrh, *nrhp; + UINT16 offset = 0; + UINT16 datasize = 0; + UINT32 sourceside_size; +@@ -4071,31 +4077,36 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size, + } + + while (rc == TPM_RC_SUCCESS) { +- nrh = array + offset; ++ /* nrhp may point to misaligned address (ubsan) ++ * we read 'into' nrh and copy to nrhp at end ++ */ ++ nrhp = array + offset; ++ + /* write the NVRAM header; + nrh->size holds the complete size including data; + nrh->size = 0 indicates the end */ +- if (offset + sizeof(nrh->size) > array_size) { +- offset += sizeof(nrh->size); ++ if (offset + sizeof(nrh.size) > array_size) { ++ offset += sizeof(nrh.size); + goto exit_size; + } + + if (rc == TPM_RC_SUCCESS) { +- rc = UINT32_Unmarshal(&nrh->size, buffer, size); +- if (nrh->size == 0) ++ rc = UINT32_Unmarshal(&nrh.size, buffer, size); ++ if (nrh.size == 0) { ++ memcpy(nrhp, &nrh, sizeof(nrh.size)); + break; ++ } + } + if (offset + sizeof(NV_RAM_HEADER) > array_size) { + offset += sizeof(NV_RAM_HEADER); + goto exit_size; + } + if (rc == TPM_RC_SUCCESS) { +- rc = TPM_HANDLE_Unmarshal(&nrh->handle, buffer, size); ++ rc = TPM_HANDLE_Unmarshal(&nrh.handle, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { +- rc = TPMA_NV_Unmarshal(&nrh->attributes, buffer, size); ++ rc = TPMA_NV_Unmarshal(&nrh.attributes, buffer, size); + } +- + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(&datasize, buffer, size); + } +@@ -4110,8 +4121,10 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size, + } + if (rc == TPM_RC_SUCCESS) { + /* fix up size in case it is architecture-dependent */ +- nrh->size = sizeof(*nrh) + datasize; +- offset += nrh->size; ++ nrh.size = sizeof(nrh) + datasize; ++ offset += nrh.size; ++ /* copy header into possibly misaligned address in NVRAM */ ++ *nrhp = nrh; + } + } + +-- +2.21.0.windows.1 +