!19 修复CVE-2021-3746

From: @jackjf
Reviewed-by: @zhujianwei001
Signed-off-by: @zhujianwei001
This commit is contained in:
openeuler-ci-bot 2021-12-06 02:08:37 +00:00 committed by Gitee
commit 3a99123b33
4 changed files with 256 additions and 2 deletions

View File

@ -6,7 +6,7 @@
%define name libtpms
%define versionx 0.7.3
%define release 4
%define release 5
# Valid crypto subsystems are 'freebl' and 'openssl'
%if "%{?crypto_subsystem}" == ""
@ -19,7 +19,7 @@
Summary: Library providing Trusted Platform Module (TPM) functionality
Name: %{name}
Version: %{versionx}
Release: 4
Release: 5
License: BSD
Group: Development/Libraries
Url: http://github.com/stefanberger/libtpms
@ -34,6 +34,9 @@ Patch4: tpm2-rev155-Add-new-RsaAdjustPrimeCandidate-code.patch
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-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
@ -126,6 +129,12 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la
%postun -p /sbin/ldconfig
%changelog
* Wed Nov 10 2021 jiangfangjie <jiangfangjie@huawei.com> - 0.7.3-5
-TYPE: CVE
-ID:NA
-ID:NA
_DESC: fix CVE-2021-3746
* Tue May 11 2021 jiangfangjie <jiangfangjie@huawei.com> - 0.7.3-4
-TYPE: CVE
-ID:NA

View File

@ -0,0 +1,155 @@
From 3aac390ce146b40117ad213c24504bb678f4daeb Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
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 <stefanb@linux.ibm.com>
---
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

View File

@ -0,0 +1,34 @@
From ea62fd9679f8c6fc5e79471b33cfbd8227bfed72 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
Date: Thu, 22 Jul 2021 21:23:58 -0400
Subject: [PATCH] tpm2: Initialize a whole OBJECT before using it
Initialize a whole OBJECT before using it. This is necessary since
an OBJECT may also be used as a HASH_OBJECT via the ANY_OBJECT
union and that HASH_OBJECT can leave bad size inidicators in TPM2B
buffer in the OBJECT. To get rid of this problem we reset the whole
OBJECT to 0 before using it. This is as if the memory for the
OBJECT was just initialized.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
src/tpm2/Object.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/tpm2/Object.c b/src/tpm2/Object.c
index ab50348..967105f 100644
--- a/src/tpm2/Object.c
+++ b/src/tpm2/Object.c
@@ -284,7 +284,8 @@ FindEmptyObjectSlot(
if(handle)
*handle = i + TRANSIENT_FIRST;
// Initialize the object attributes
- MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES));
+ // MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES));
+ MemorySet(object, 0, sizeof(*object)); // libtpms added: Initialize the whole object
return object;
}
}
--
2.21.0.windows.1

View File

@ -0,0 +1,56 @@
From 1fb6cd9b8df05b5d6e381b31215193d6ada969df Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
Date: Fri, 23 Jul 2021 13:29:00 -0400
Subject: [PATCH] tpm2: NVMarshal: Handle index orderly RAM without 0-sized
terminating node
The NVRAM entries in s_indexOrderlyRam array do not need to contain a
0-sized terminating node. Instead, the entries may fill up this 512
byte array so that no NV_RAM_HEADER structure fits anymore. The fact
that no more NV_RAM_HEADER structure fits is also an indicator for the
last entry. We need to account for this in the code marshalling and
unmarshalling the entries so that we stop marshalling the entries
then and similarly stop unmarshalling.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
src/tpm2/NVMarshal.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c
index 2b2d84a..430f481 100644
--- a/src/tpm2/NVMarshal.c
+++ b/src/tpm2/NVMarshal.c
@@ -4103,6 +4103,12 @@ INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size,
datasize, buffer, size);
}
offset += nrh.size;
+ if (offset + sizeof(NV_RAM_HEADER) > array_size) {
+ /* nothing will fit anymore and there won't be a 0-sized
+ * terminating node (@1).
+ */
+ break;
+ }
}
written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
@@ -4144,6 +4150,16 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size,
*/
nrhp = array + offset;
+ if (offset + sizeof(NV_RAM_HEADER) > sourceside_size) {
+ /* this case can occur with the previous entry filling up the
+ * space; in this case there will not be a 0-sized terminating
+ * node (see @1 above). We clear the rest of our space.
+ */
+ if (array_size > offset)
+ memset(nrhp, 0, array_size - offset);
+ break;
+ }
+
/* write the NVRAM header;
nrh->size holds the complete size including data;
nrh->size = 0 indicates the end */
--
2.21.0.windows.1