diff --git a/0001-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch b/0001-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch deleted file mode 100644 index f07e304f6a76d2db2d88a3081673da5c165b8b21..0000000000000000000000000000000000000000 --- a/0001-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 85a19a714c4b4702edc59db0a3419f48fffe2b0a Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 17 Feb 2022 17:38:41 +0800 -Subject: [PATCH] OvmfPkg: VirtioNetDxe: Extend the RxBufferSize to avoid data - truncation - -1822 net card needs at least 1536 bytes for DMA, even we never negotiate -VIRTIO_NET_F_MRG_RXBUF. The original max size of packet is 15144 which would -cause data trucation. Now we extend the RxBufSize to 9014(Jumbo Frame type) -so that we can avoid it. - -Signed-off-by: Jinhua Cao ---- - OvmfPkg/Include/IndustryStandard/Virtio095Net.h | 7 +++++++ - OvmfPkg/VirtioNetDxe/SnpInitialize.c | 3 ++- - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/OvmfPkg/Include/IndustryStandard/Virtio095Net.h b/OvmfPkg/Include/IndustryStandard/Virtio095Net.h -index 9c0ed5ed24..28f5cc0899 100644 ---- a/OvmfPkg/Include/IndustryStandard/Virtio095Net.h -+++ b/OvmfPkg/Include/IndustryStandard/Virtio095Net.h -@@ -88,4 +88,11 @@ typedef struct { - #define VIRTIO_NET_S_LINK_UP BIT0 - #define VIRTIO_NET_S_ANNOUNCE BIT1 - -+// -+// 1822 net card needs at least 1536 bytes for DMA, even we never negotiate -+// VIRTIO_NET_F_MRG_RXBUF. The original max size of packet is 15144 which would -+// cause data trucation. Now we extend the RxBufSize to 9014(Jumbo Frame type) -+// so that we can avoid it. -+#define VIRTIO_RXBUF_JUMBO_PADDING 7500 -+ - #endif // _VIRTIO_0_9_5_NET_H_ -diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c -index bb3b552d68..6febfea3bb 100644 ---- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c -+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c -@@ -337,7 +337,8 @@ VirtioNetInitRx ( - // and Ethernet payload). - // - RxBufSize = VirtioNetReqSize + -- (Dev->Snm.MediaHeaderSize + Dev->Snm.MaxPacketSize); -+ (Dev->Snm.MediaHeaderSize + Dev->Snm.MaxPacketSize) + -+ VIRTIO_RXBUF_JUMBO_PADDING; - - // - // Limit the number of pending RX packets if the queue is big. The division --- -2.27.0 - diff --git a/0002-add-Wno-maybe-uninitialized-to-fix-build-error.patch b/0002-add-Wno-maybe-uninitialized-to-fix-build-error.patch deleted file mode 100644 index 8eeeca1a2a5d9566a109c2ea8d7b9379e3a76ab0..0000000000000000000000000000000000000000 --- a/0002-add-Wno-maybe-uninitialized-to-fix-build-error.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f517ad5c6b7fab267f3beb9f87ea608e6b2875df Mon Sep 17 00:00:00 2001 -From: ouuleilei -Date: Fri, 18 Aug 2023 09:28:16 +0800 -Subject: [PATCH] add -Wno-maybe-uninitialized to fix build error - ---- - BaseTools/Conf/tools_def.template | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template -index 503a668..b3872c0 100755 ---- a/BaseTools/Conf/tools_def.template -+++ b/BaseTools/Conf/tools_def.template -@@ -852,7 +852,7 @@ DEFINE GCC5_RISCV_ALL_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sec - DEFINE GCC5_RISCV_ALL_DLINK_FLAGS = DEF(GCC5_RISCV_ALL_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map - DEFINE GCC5_RISCV_ALL_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds - DEFINE GCC5_RISCV_ALL_ASM_FLAGS = -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h --DEFINE GCC5_RISCV_ALL_CC_FLAGS_WARNING_DISABLE = -Wno-tautological-compare -Wno-pointer-compare -+DEFINE GCC5_RISCV_ALL_CC_FLAGS_WARNING_DISABLE = -Wno-tautological-compare -Wno-pointer-compare -Wno-maybe-uninitialized - - DEFINE GCC5_RISCV_OPENSBI_TYPES = -DOPENSBI_EXTERNAL_SBI_TYPES=OpensbiTypes.h - --- -2.39.1 - diff --git a/0003-Add-testcases-for-empty-associated-data-entries-with.patch b/0003-Add-testcases-for-empty-associated-data-entries-with.patch deleted file mode 100644 index bf7153287c62feaad6e32f124e73de8a0eca9947..0000000000000000000000000000000000000000 --- a/0003-Add-testcases-for-empty-associated-data-entries-with.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 02ea09fc1e2ca35033db52384543c47329d3566f Mon Sep 17 00:00:00 2001 -From: Tomas Mraz -Date: Tue, 4 Jul 2023 17:50:37 +0200 -Subject: [PATCH 1/9] Add testcases for empty associated data entries with - AES-SIV - -CVE-2023-2975 - -Reviewed-by: Matt Caswell -Reviewed-by: Paul Dale - -reference: https://github.com/openssl/openssl/pull/21384 -Signed-off-by: yexiao ---- - .../30-test_evp_data/evpciph_aes_siv.txt | 31 +++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt -index a78a4915..e434f13f 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt -@@ -20,6 +20,19 @@ Tag = 85632d07c6e8f37f950acd320a2ecc93 - Plaintext = 112233445566778899aabbccddee - Ciphertext = 40c02b9690c4dc04daef7f6afe5c - -+Cipher = aes-128-siv -+Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff -+Tag = f1c5fdeac1f15a26779c1501f9fb7588 -+Plaintext = 112233445566778899aabbccddee -+Ciphertext = 27e946c669088ab06da58c5c831c -+ -+Cipher = aes-128-siv -+Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff -+AAD = -+Tag = d1022f5b3664e5a4dfaf90f85be6f28a -+Plaintext = 112233445566778899aabbccddee -+Ciphertext = b66cff6b8eca0b79f083b39a0901 -+ - Cipher = aes-128-siv - Key = 7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f - AAD = 00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100 -@@ -29,6 +42,24 @@ Tag = 7bdb6e3b432667eb06f4d14bff2fbd0f - Plaintext = 7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553 - Ciphertext = cb900f2fddbe404326601965c889bf17dba77ceb094fa663b7a3f748ba8af829ea64ad544a272e9c485b62a3fd5c0d - -+Cipher = aes-128-siv -+Key = 7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f -+AAD = 00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100 -+AAD = -+AAD = 09f911029d74e35bd84156c5635688c0 -+Tag = 83ce6593a8fa67eb6fcd2819cedfc011 -+Plaintext = 7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553 -+Ciphertext = 30d937b42f71f71f93fc2d8d702d3eac8dc7651eefcd81120081ff29d626f97f3de17f2969b691c91b69b652bf3a6d -+ -+Cipher = aes-128-siv -+Key = 7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f -+AAD = -+AAD = 00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100 -+AAD = 09f911029d74e35bd84156c5635688c0 -+Tag = 77dd4a44f5a6b41302121ee7f378de25 -+Plaintext = 7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553 -+Ciphertext = 0fcd664c922464c88939d71fad7aefb864e501b0848a07d39201c1067a7288f3dadf0131a823a0bc3d588e8564a5fe -+ - Cipher = aes-192-siv - Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfefffffefdfcfbfaf9f8f7f6f5f4f3f2f1f0 - AAD = 101112131415161718191a1b1c1d1e1f2021222324252627 --- -2.33.0 - diff --git a/0004-Do-not-ignore-empty-associated-data-with-AES-SIV-mod.patch b/0004-Do-not-ignore-empty-associated-data-with-AES-SIV-mod.patch deleted file mode 100644 index b4c32afa99c2ae79450926e51e83ef8d3a9fe722..0000000000000000000000000000000000000000 --- a/0004-Do-not-ignore-empty-associated-data-with-AES-SIV-mod.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 7058d271753e1c2ca7d9384e09fd84b98e92c440 Mon Sep 17 00:00:00 2001 -From: Tomas Mraz -Date: Tue, 4 Jul 2023 17:30:35 +0200 -Subject: [PATCH 2/9] Do not ignore empty associated data with AES-SIV mode - -The AES-SIV mode allows for multiple associated data items -authenticated separately with any of these being 0 length. - -The provided implementation ignores such empty associated data -which is incorrect in regards to the RFC 5297 and is also -a security issue because such empty associated data then become -unauthenticated if an application expects to authenticate them. - -Fixes CVE-2023-2975 - -Reviewed-by: Matt Caswell -Reviewed-by: Paul Dale - -reference: https://github.com/openssl/openssl/pull/21384 -Signed-off-by: yexiao ---- - .../implementations/ciphers/cipher_aes_siv.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/providers/implementations/ciphers/cipher_aes_siv.c b/CryptoPkg/Library/OpensslLib/openssl/providers/implementations/ciphers/cipher_aes_siv.c -index 45010b90..b396c865 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/providers/implementations/ciphers/cipher_aes_siv.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/providers/implementations/ciphers/cipher_aes_siv.c -@@ -120,14 +120,18 @@ static int siv_cipher(void *vctx, unsigned char *out, size_t *outl, - if (!ossl_prov_is_running()) - return 0; - -- if (inl == 0) { -- *outl = 0; -- return 1; -- } -+ /* Ignore just empty encryption/decryption call and not AAD. */ -+ if (out != NULL) { -+ if (inl == 0) { -+ if (outl != NULL) -+ *outl = 0; -+ return 1; -+ } - -- if (outsize < inl) { -- ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); -- return 0; -+ if (outsize < inl) { -+ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); -+ return 0; -+ } - } - - if (ctx->hw->cipher(ctx, out, in, inl) <= 0) --- -2.33.0 - diff --git a/0005-Add-a-test-for-CVE-2023-3446.patch b/0005-Add-a-test-for-CVE-2023-3446.patch deleted file mode 100644 index d59699207a3a5bd9d5be4aa2808489aa80bd2fe6..0000000000000000000000000000000000000000 --- a/0005-Add-a-test-for-CVE-2023-3446.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3a2feb831096ede8621a9ae9053b48f732dc30b1 Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Fri, 7 Jul 2023 14:39:48 +0100 -Subject: [PATCH 3/9] Add a test for CVE-2023-3446 - -Confirm that the only errors DH_check() finds with DH parameters with an -excessively long modulus is that the modulus is too large. We should not -be performing time consuming checks using that modulus. - -Reviewed-by: Paul Dale -Reviewed-by: Tom Cosgrove -Reviewed-by: Bernd Edlinger -Reviewed-by: Tomas Mraz - -reference: https://github.com/openssl/openssl/pull/21451 -Signed-off-by: yexiao ---- - .../Library/OpensslLib/openssl/test/dhtest.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c -index 7b587f3c..f8dd8f3a 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c -@@ -73,7 +73,7 @@ static int dh_test(void) - goto err1; - - /* check fails, because p is way too small */ -- if (!DH_check(dh, &i)) -+ if (!TEST_true(DH_check(dh, &i))) - goto err2; - i ^= DH_MODULUS_TOO_SMALL; - if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) -@@ -124,6 +124,17 @@ static int dh_test(void) - /* We'll have a stale error on the queue from the above test so clear it */ - ERR_clear_error(); - -+ /* Modulus of size: dh check max modulus bits + 1 */ -+ if (!TEST_true(BN_set_word(p, 1)) -+ || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS))) -+ goto err3; -+ -+ /* -+ * We expect no checks at all for an excessively large modulus -+ */ -+ if (!TEST_false(DH_check(dh, &i))) -+ goto err3; -+ - /* - * II) key generation - */ -@@ -138,7 +149,7 @@ static int dh_test(void) - goto err3; - - /* ... and check whether it is valid */ -- if (!DH_check(a, &i)) -+ if (!TEST_true(DH_check(a, &i))) - goto err3; - if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) - || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME) --- -2.33.0 - diff --git a/0006-Fix-DH_check-excessive-time-with-over-sized-modulus.patch b/0006-Fix-DH_check-excessive-time-with-over-sized-modulus.patch deleted file mode 100644 index 68bf2d20492919a23325a76105cea322a032d49f..0000000000000000000000000000000000000000 --- a/0006-Fix-DH_check-excessive-time-with-over-sized-modulus.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 96452ca9276610c46b7cb61f9efaf787bea627d0 Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Thu, 6 Jul 2023 16:36:35 +0100 -Subject: [PATCH 4/9] Fix DH_check() excessive time with over sized modulus - -The DH_check() function checks numerous aspects of the key or parameters -that have been supplied. Some of those checks use the supplied modulus -value even if it is excessively large. - -There is already a maximum DH modulus size (10,000 bits) over which -OpenSSL will not generate or derive keys. DH_check() will however still -perform various tests for validity on such a large modulus. We introduce a -new maximum (32,768) over which DH_check() will just fail. - -An application that calls DH_check() and supplies a key or parameters -obtained from an untrusted source could be vulnerable to a Denial of -Service attack. - -The function DH_check() is itself called by a number of other OpenSSL -functions. An application calling any of those other functions may -similarly be affected. The other functions affected by this are -DH_check_ex() and EVP_PKEY_param_check(). - -CVE-2023-3446 - -Reviewed-by: Paul Dale -Reviewed-by: Tom Cosgrove -Reviewed-by: Bernd Edlinger -Reviewed-by: Tomas Mraz - -reference: https://github.com/openssl/openssl/pull/21451 -Signed-off-by: yexiao ---- - CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c | 6 ++++++ - CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h | 6 +++++- - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -index 0b391910..84a92699 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -@@ -152,6 +152,12 @@ int DH_check(const DH *dh, int *ret) - if (nid != NID_undef) - return 1; - -+ /* Don't do any checks at all with an excessively large modulus */ -+ if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { -+ ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); -+ return 0; -+ } -+ - if (!DH_check_params(dh, ret)) - return 0; - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h -index b97871ec..36420f51 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h -+++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h -@@ -89,7 +89,11 @@ int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); - # include - - # ifndef OPENSSL_DH_MAX_MODULUS_BITS --# define OPENSSL_DH_MAX_MODULUS_BITS 10000 -+# define OPENSSL_DH_MAX_MODULUS_BITS 10000 -+# endif -+ -+# ifndef OPENSSL_DH_CHECK_MAX_MODULUS_BITS -+# define OPENSSL_DH_CHECK_MAX_MODULUS_BITS 32768 - # endif - - # define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 --- -2.33.0 - diff --git a/0007-Make-DH_check-set-some-error-bits-in-recently-added-.patch b/0007-Make-DH_check-set-some-error-bits-in-recently-added-.patch deleted file mode 100644 index 7d7047eb5ff613734cf346f534ef31d19cabf2d9..0000000000000000000000000000000000000000 --- a/0007-Make-DH_check-set-some-error-bits-in-recently-added-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 66ed0773fff248363b63273f78de8fe6da87a8b4 Mon Sep 17 00:00:00 2001 -From: Bernd Edlinger -Date: Sun, 23 Jul 2023 14:27:54 +0200 -Subject: [PATCH 5/9] Make DH_check set some error bits in recently added error - -The pre-existing error cases where DH_check returned zero -are not related to the dh params in any way, but are only -triggered by out-of-memory errors, therefore having *ret -set to zero feels right, but since the new error case is -triggered by too large p values that is something different. -On the other hand some callers of this function might not -be prepared to handle the return value correctly but only -rely on *ret. Therefore we set some error bits in *ret as -additional safety measure. - -Reviewed-by: Paul Dale -Reviewed-by: Tomas Mraz - -reference: https://github.com/openssl/openssl/pull/21524 -Signed-off-by: yexiao ---- - CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -index 84a92699..aef6f9b1 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -@@ -155,6 +155,7 @@ int DH_check(const DH *dh, int *ret) - /* Don't do any checks at all with an excessively large modulus */ - if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { - ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); -+ *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_P_NOT_PRIME; - return 0; - } - --- -2.33.0 - diff --git a/0008-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch b/0008-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch deleted file mode 100644 index 2eb03ab804ef9fc3e32f915d4a1b4d016ee46557..0000000000000000000000000000000000000000 --- a/0008-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7d3ba65d3f707ba29c854e6b1c73a68c941041ba Mon Sep 17 00:00:00 2001 -From: Tomas Mraz -Date: Tue, 25 Jul 2023 15:22:48 +0200 -Subject: [PATCH 6/9] DH_check(): Do not try checking q properties if it is - obviously invalid - -If |q| >= |p| then the q value is obviously wrong as q -is supposed to be a prime divisor of p-1. - -We check if p is overly large so this added test implies that -q is not large either when performing subsequent tests using that -q value. - -Otherwise if it is too large these additional checks of the q value -such as the primality test can then trigger DoS by doing overly long -computations. - -Fixes CVE-2023-3817 - -Reviewed-by: Matt Caswell -Reviewed-by: Paul Dale -Reviewed-by: Tom Cosgrove -Reviewed-by: Todd Short - -reference: https://github.com/openssl/openssl/pull/21550 -Signed-off-by: yexiao ---- - .../Library/OpensslLib/openssl/crypto/dh/dh_check.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -index aef6f9b1..fbe27975 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c -@@ -143,7 +143,7 @@ int DH_check(const DH *dh, int *ret) - #ifdef FIPS_MODULE - return DH_check_params(dh, ret); - #else -- int ok = 0, r; -+ int ok = 0, r, q_good = 0; - BN_CTX *ctx = NULL; - BIGNUM *t1 = NULL, *t2 = NULL; - int nid = DH_get_nid((DH *)dh); -@@ -172,6 +172,13 @@ int DH_check(const DH *dh, int *ret) - goto err; - - if (dh->params.q != NULL) { -+ if (BN_ucmp(dh->params.p, dh->params.q) > 0) -+ q_good = 1; -+ else -+ *ret |= DH_CHECK_INVALID_Q_VALUE; -+ } -+ -+ if (q_good) { - if (BN_cmp(dh->params.g, BN_value_one()) <= 0) - *ret |= DH_NOT_SUITABLE_GENERATOR; - else if (BN_cmp(dh->params.g, dh->params.p) >= 0) --- -2.33.0 - diff --git a/0009-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch b/0009-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch deleted file mode 100644 index 91a17dd00762cfe2765f009f5da867130571c616..0000000000000000000000000000000000000000 --- a/0009-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 6f3b1ae0a836880038787a1315b5b815f2951c8d Mon Sep 17 00:00:00 2001 -From: Tomas Mraz -Date: Tue, 25 Jul 2023 15:23:43 +0200 -Subject: [PATCH 7/9] dhtest.c: Add test of DH_check() with q = p + 1 - -This must fail with DH_CHECK_INVALID_Q_VALUE and -with DH_CHECK_Q_NOT_PRIME unset. - -Reviewed-by: Matt Caswell -Reviewed-by: Paul Dale -Reviewed-by: Tom Cosgrove -Reviewed-by: Todd Short - -reference: https://github.com/openssl/openssl/pull/21550 -Signed-off-by: yexiao ---- - CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c -index f8dd8f3a..d02b3b7c 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c -@@ -124,6 +124,15 @@ static int dh_test(void) - /* We'll have a stale error on the queue from the above test so clear it */ - ERR_clear_error(); - -+ if (!TEST_ptr(BN_copy(q, p)) || !TEST_true(BN_add(q, q, BN_value_one()))) -+ goto err3; -+ -+ if (!TEST_true(DH_check(dh, &i))) -+ goto err3; -+ if (!TEST_true(i & DH_CHECK_INVALID_Q_VALUE) -+ || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)) -+ goto err3; -+ - /* Modulus of size: dh check max modulus bits + 1 */ - if (!TEST_true(BN_set_word(p, 1)) - || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS))) -@@ -135,6 +144,9 @@ static int dh_test(void) - if (!TEST_false(DH_check(dh, &i))) - goto err3; - -+ /* We'll have a stale error on the queue from the above test so clear it */ -+ ERR_clear_error(); -+ - /* - * II) key generation - */ --- -2.33.0 - diff --git a/0010-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch b/0010-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch deleted file mode 100644 index 36049b2e3113527420921143717c71a59361f702..0000000000000000000000000000000000000000 --- a/0010-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 6b5fa79607808b28830ac267253dfbf6ed9c463c Mon Sep 17 00:00:00 2001 -From: liwei -Date: Fri, 26 Jan 2024 18:45:28 +0800 -Subject: [PATCH] Add NULL checks where ContentInfo data can be NULL - -PKCS12 structures contain PKCS7 ContentInfo fields. These fields are -optional and can be NULL even if the "type" is a valid value. OpenSSL -was not properly accounting for this and a NULL dereference can occur -causing a crash. - -CVE-2024-0727 - -Reviewed-by: Tomas Mraz -Reviewed-by: Hugo Landau -Reviewed-by: Neil Horman - -reference: https://github.com/openssl/openssl/commit/09df4395b5071217b76dc7d3d2e630eb8c5a79c2 -Signed-off-by: yexiao ---- - .../OpensslLib/openssl/crypto/pkcs12/p12_add.c | 18 ++++++++++++++++++ - .../openssl/crypto/pkcs12/p12_mutl.c | 5 +++++ - .../openssl/crypto/pkcs12/p12_npas.c | 5 +++-- - .../OpensslLib/openssl/crypto/pkcs7/pk7_mime.c | 7 +++++-- - 4 files changed, 31 insertions(+), 4 deletions(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c -index 6fd4184a..80ce31b3 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c -@@ -78,6 +78,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) - ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); - return NULL; - } -+ -+ if (p7->d.data == NULL) { -+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); -+ return NULL; -+ } -+ - return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); - } - -@@ -150,6 +156,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, - { - if (!PKCS7_type_is_encrypted(p7)) - return NULL; -+ -+ if (p7->d.encrypted == NULL) { -+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); -+ return NULL; -+ } -+ - return PKCS12_item_decrypt_d2i_ex(p7->d.encrypted->enc_data->algorithm, - ASN1_ITEM_rptr(PKCS12_SAFEBAGS), - pass, passlen, -@@ -188,6 +200,12 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) - ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); - return NULL; - } -+ -+ if (p12->authsafes->d.data == NULL) { -+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); -+ return NULL; -+ } -+ - p7s = ASN1_item_unpack(p12->authsafes->d.data, - ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); - if (p7s != NULL) { -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c -index afdb8d68..67be81eb 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c -@@ -98,6 +98,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, - return 0; - } - -+ if (p12->authsafes->d.data == NULL) { -+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); -+ return 0; -+ } -+ - salt = p12->mac->salt->data; - saltlen = p12->mac->salt->length; - if (p12->mac->iter == NULL) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c -index 62230bc6..1e5b5495 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c -@@ -77,8 +77,9 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) - bags = PKCS12_unpack_p7data(p7); - } else if (bagnid == NID_pkcs7_encrypted) { - bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); -- if (!alg_get(p7->d.encrypted->enc_data->algorithm, -- &pbe_nid, &pbe_iter, &pbe_saltlen)) -+ if (p7->d.encrypted == NULL -+ || !alg_get(p7->d.encrypted->enc_data->algorithm, -+ &pbe_nid, &pbe_iter, &pbe_saltlen)) - goto err; - } else { - continue; -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c -index 49a0da5f..8228315e 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c -@@ -33,10 +33,13 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) - int ctype_nid = OBJ_obj2nid(p7->type); - const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7); - -- if (ctype_nid == NID_pkcs7_signed) -+ if (ctype_nid == NID_pkcs7_signed) { -+ if (p7->d.sign == NULL) -+ return 0; - mdalgs = p7->d.sign->md_algs; -- else -+ } else { - mdalgs = NULL; -+ } - - flags ^= SMIME_OLDMIME; - --- -2.33.0 - diff --git a/0011-poly1305-ppc.pl-Fix-vector-register-clobbering.patch b/0011-poly1305-ppc.pl-Fix-vector-register-clobbering.patch deleted file mode 100644 index 1be35a919b9952cad31fc03379da798549e074c4..0000000000000000000000000000000000000000 --- a/0011-poly1305-ppc.pl-Fix-vector-register-clobbering.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 1df7dcaa6684420a74e6f935e0b5290fb616d5a8 Mon Sep 17 00:00:00 2001 -From: Rohan McLure -Date: Thu, 4 Jan 2024 10:25:50 +0100 -Subject: [PATCH 9/9] poly1305-ppc.pl: Fix vector register clobbering - -Fixes CVE-2023-6129 - -The POLY1305 MAC (message authentication code) implementation in OpenSSL for -PowerPC CPUs saves the the contents of vector registers in different order -than they are restored. Thus the contents of some of these vector registers -is corrupted when returning to the caller. The vulnerable code is used only -on newer PowerPC processors supporting the PowerISA 2.07 instructions. - -Reviewed-by: Matt Caswell -Reviewed-by: Richard Levitte -Reviewed-by: Tomas Mraz - -reference: https://github.com/openssl/openssl/pull/23200 -Signed-off-by: yexiao ---- - .../crypto/poly1305/asm/poly1305-ppc.pl | 42 +++++++++---------- - 1 file changed, 21 insertions(+), 21 deletions(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl -index 9f86134d..2e601bb9 100755 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl -@@ -744,7 +744,7 @@ ___ - my $LOCALS= 6*$SIZE_T; - my $VSXFRAME = $LOCALS + 6*$SIZE_T; - $VSXFRAME += 128; # local variables -- $VSXFRAME += 13*16; # v20-v31 offload -+ $VSXFRAME += 12*16; # v20-v31 offload - - my $BIG_ENDIAN = ($flavour !~ /le/) ? 4 : 0; - -@@ -919,12 +919,12 @@ __poly1305_blocks_vsx: - addi r11,r11,32 - stvx v22,r10,$sp - addi r10,r10,32 -- stvx v23,r10,$sp -- addi r10,r10,32 -- stvx v24,r11,$sp -+ stvx v23,r11,$sp - addi r11,r11,32 -- stvx v25,r10,$sp -+ stvx v24,r10,$sp - addi r10,r10,32 -+ stvx v25,r11,$sp -+ addi r11,r11,32 - stvx v26,r10,$sp - addi r10,r10,32 - stvx v27,r11,$sp -@@ -1153,12 +1153,12 @@ __poly1305_blocks_vsx: - addi r11,r11,32 - stvx v22,r10,$sp - addi r10,r10,32 -- stvx v23,r10,$sp -- addi r10,r10,32 -- stvx v24,r11,$sp -+ stvx v23,r11,$sp - addi r11,r11,32 -- stvx v25,r10,$sp -+ stvx v24,r10,$sp - addi r10,r10,32 -+ stvx v25,r11,$sp -+ addi r11,r11,32 - stvx v26,r10,$sp - addi r10,r10,32 - stvx v27,r11,$sp -@@ -1899,26 +1899,26 @@ Ldone_vsx: - mtspr 256,r12 # restore vrsave - lvx v20,r10,$sp - addi r10,r10,32 -- lvx v21,r10,$sp -- addi r10,r10,32 -- lvx v22,r11,$sp -+ lvx v21,r11,$sp - addi r11,r11,32 -- lvx v23,r10,$sp -+ lvx v22,r10,$sp - addi r10,r10,32 -- lvx v24,r11,$sp -+ lvx v23,r11,$sp - addi r11,r11,32 -- lvx v25,r10,$sp -+ lvx v24,r10,$sp - addi r10,r10,32 -- lvx v26,r11,$sp -+ lvx v25,r11,$sp - addi r11,r11,32 -- lvx v27,r10,$sp -+ lvx v26,r10,$sp - addi r10,r10,32 -- lvx v28,r11,$sp -+ lvx v27,r11,$sp - addi r11,r11,32 -- lvx v29,r10,$sp -+ lvx v28,r10,$sp - addi r10,r10,32 -- lvx v30,r11,$sp -- lvx v31,r10,$sp -+ lvx v29,r11,$sp -+ addi r11,r11,32 -+ lvx v30,r10,$sp -+ lvx v31,r11,$sp - $POP r27,`$VSXFRAME-$SIZE_T*5`($sp) - $POP r28,`$VSXFRAME-$SIZE_T*4`($sp) - $POP r29,`$VSXFRAME-$SIZE_T*3`($sp) --- -2.33.0 - diff --git a/0012-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch b/0012-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch deleted file mode 100644 index 5f204801253d432ce332e4bb85df1a0b97ee7503..0000000000000000000000000000000000000000 --- a/0012-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch +++ /dev/null @@ -1,995 +0,0 @@ -From 1adc7d6bea3bcd15f8ce5040b99c12665dcb240e Mon Sep 17 00:00:00 2001 -From: "Douglas Flick [MSFT]" -Date: Fri, 12 Jan 2024 02:16:01 +0800 -Subject: [PATCH 01/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4117 - - CVE 2022-36763 - -This commit contains the patch files and tests for DxeTpm2MeasureBootLib -CVE 2022-36763. - -Cc: Jiewen Yao - -Signed-off-by: Doug Flick [MSFT] - -reference: https://github.com/tianocore/edk2/pull/5264 -Signed-off-by: yexiao ---- - .../DxeTpm2MeasureBootLib.c | 69 ++-- - .../DxeTpm2MeasureBootLib.inf | 4 +- - .../DxeTpm2MeasureBootLibSanitization.c | 275 ++++++++++++++++ - .../DxeTpm2MeasureBootLibSanitization.h | 113 +++++++ - .../DxeTpm2MeasureBootLibSanitizationTest.c | 303 ++++++++++++++++++ - ...Tpm2MeasureBootLibSanitizationTestHost.inf | 28 ++ - SecurityPkg/SecurityPkg.ci.yaml | 1 + - SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 + - 8 files changed, 764 insertions(+), 30 deletions(-) - create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c - create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h - create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c - create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf - -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -index 36a256a7..0a37a4b6 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -@@ -20,6 +20,8 @@ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
- (C) Copyright 2015 Hewlett Packard Enterprise Development LP
- SPDX-License-Identifier: BSD-2-Clause-Patent - -+Copyright (c) Microsoft Corporation.
-+SPDX-License-Identifier: BSD-2-Clause-Patent - **/ - - #include -@@ -44,6 +46,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - #include - #include - -+#include "DxeTpm2MeasureBootLibSanitization.h" -+ - typedef struct { - EFI_TCG2_PROTOCOL *Tcg2Protocol; - EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol; -@@ -144,10 +148,11 @@ Tcg2MeasureGptTable ( - EFI_TCG2_EVENT *Tcg2Event; - EFI_CC_EVENT *CcEvent; - EFI_GPT_DATA *GptData; -- UINT32 EventSize; -+ UINT32 TcgEventSize; - EFI_TCG2_PROTOCOL *Tcg2Protocol; - EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol; - EFI_CC_MR_INDEX MrIndex; -+ UINT32 AllocSize; - - if (mTcg2MeasureGptCount > 0) { - return EFI_SUCCESS; -@@ -195,25 +200,22 @@ Tcg2MeasureGptTable ( - BlockIo->Media->BlockSize, - (UINT8 *)PrimaryHeader - ); -- if (EFI_ERROR (Status)) { -- DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); -+ if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { -+ DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); - FreePool (PrimaryHeader); - return EFI_DEVICE_ERROR; - } - - // -- // PrimaryHeader->SizeOfPartitionEntry should not be zero -+ // Read the partition entry. - // -- if (PrimaryHeader->SizeOfPartitionEntry == 0) { -- DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry should not be zero!\n")); -+ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); -+ if (EFI_ERROR (Status)) { - FreePool (PrimaryHeader); - return EFI_BAD_BUFFER_SIZE; - } - -- // -- // Read the partition entry. -- // -- EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); -+ EntryPtr = (UINT8 *)AllocatePool (AllocSize); - if (EntryPtr == NULL) { - FreePool (PrimaryHeader); - return EFI_OUT_OF_RESOURCES; -@@ -223,7 +225,7 @@ Tcg2MeasureGptTable ( - DiskIo, - BlockIo->Media->MediaId, - MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), -- PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, -+ AllocSize, - EntryPtr - ); - if (EFI_ERROR (Status)) { -@@ -248,16 +250,21 @@ Tcg2MeasureGptTable ( - // - // Prepare Data for Measurement (CcProtocol and Tcg2Protocol) - // -- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) -- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); -- EventPtr = (UINT8 *)AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)); -+ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); -+ if (EFI_ERROR (Status)) { -+ FreePool (PrimaryHeader); -+ FreePool (EntryPtr); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ EventPtr = (UINT8 *)AllocateZeroPool (TcgEventSize); - if (EventPtr == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - Tcg2Event = (EFI_TCG2_EVENT *)EventPtr; -- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); -+ Tcg2Event->Size = TcgEventSize; - Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); - Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION; - Tcg2Event->Header.PCRIndex = 5; -@@ -310,7 +317,7 @@ Tcg2MeasureGptTable ( - CcProtocol, - 0, - (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData, -- (UINT64)EventSize, -+ (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event), - CcEvent - ); - if (!EFI_ERROR (Status)) { -@@ -326,7 +333,7 @@ Tcg2MeasureGptTable ( - Tcg2Protocol, - 0, - (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData, -- (UINT64)EventSize, -+ (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event), - Tcg2Event - ); - if (!EFI_ERROR (Status)) { -@@ -443,11 +450,13 @@ Tcg2MeasurePeImage ( - Tcg2Event->Header.PCRIndex = 2; - break; - default: -- DEBUG (( -- DEBUG_ERROR, -- "Tcg2MeasurePeImage: Unknown subsystem type %d", -- ImageType -- )); -+ DEBUG ( -+ ( -+ DEBUG_ERROR, -+ "Tcg2MeasurePeImage: Unknown subsystem type %d", -+ ImageType -+ ) -+ ); - goto Finish; - } - -@@ -515,7 +524,7 @@ Finish: - - @param MeasureBootProtocols Pointer to the located measure boot protocol instances. - -- @retval EFI_SUCCESS Sucessfully locate the measure boot protocol instances (at least one instance). -+ @retval EFI_SUCCESS Successfully locate the measure boot protocol instances (at least one instance). - @retval EFI_UNSUPPORTED Measure boot is not supported. - **/ - EFI_STATUS -@@ -646,12 +655,14 @@ DxeTpm2MeasureBootHandler ( - return EFI_SUCCESS; - } - -- DEBUG (( -- DEBUG_INFO, -- "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n", -- MeasureBootProtocols.Tcg2Protocol, -- MeasureBootProtocols.CcProtocol -- )); -+ DEBUG ( -+ ( -+ DEBUG_INFO, -+ "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n", -+ MeasureBootProtocols.Tcg2Protocol, -+ MeasureBootProtocols.CcProtocol -+ ) -+ ); - - // - // Copy File Device Path -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf -index 6dca79a2..78395573 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf -@@ -37,6 +37,8 @@ - - [Sources] - DxeTpm2MeasureBootLib.c -+ DxeTpm2MeasureBootLibSanitization.c -+ DxeTpm2MeasureBootLibSanitization.h - - [Packages] - MdePkg/MdePkg.dec -@@ -46,6 +48,7 @@ - - [LibraryClasses] - BaseMemoryLib -+ SafeIntLib - DebugLib - MemoryAllocationLib - DevicePathLib -@@ -65,4 +68,3 @@ - gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES - gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES -- -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -new file mode 100644 -index 00000000..ef3b77b4 ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -@@ -0,0 +1,275 @@ -+/** @file -+ The library instance provides security service of TPM2 measure boot and -+ Confidential Computing (CC) measure boot. -+ -+ Caution: This file requires additional review when modified. -+ This library will have external input - PE/COFF image and GPT partition. -+ This external input must be validated carefully to avoid security issue like -+ buffer overflow, integer overflow. -+ -+ This file will pull out the validation logic from the following functions, in an -+ attempt to validate the untrusted input in the form of unit tests -+ -+ These are those functions: -+ -+ DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content -+ read is within the image buffer. -+ -+ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse -+ partition data carefully. -+ -+ Copyright (c) Microsoft Corporation.
-+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "DxeTpm2MeasureBootLibSanitization.h" -+ -+#define GPT_HEADER_REVISION_V1 0x00010000 -+ -+/** -+ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse -+ However this function will not attempt to verify the validity of the GPT partition -+ It will check the following: -+ - Signature -+ - Revision -+ - AlternateLBA -+ - FirstUsableLBA -+ - LastUsableLBA -+ - PartitionEntryLBA -+ - NumberOfPartitionEntries -+ - SizeOfPartitionEntry -+ - BlockIo -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[in] BlockIo -+ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. -+ -+ @retval EFI_SUCCESS -+ The EFI_PARTITION_TABLE_HEADER structure is valid. -+ -+ @retval EFI_INVALID_PARAMETER -+ The EFI_PARTITION_TABLE_HEADER structure is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizeEfiPartitionTableHeader ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo -+ ) -+{ -+ // -+ // Verify that the input parameters are safe to use -+ // -+ if (PrimaryHeader == NULL) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if ((BlockIo == NULL) || (BlockIo->Media == NULL)) { -+ DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) -+ // -+ if (PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // The version must be GPT_HEADER_REVISION_V1 (0x00010000) -+ // -+ if (PrimaryHeader->Header.Revision != GPT_HEADER_REVISION_V1) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size -+ // -+ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // The partition entries should all be before the first usable block -+ // -+ if (PrimaryHeader->FirstUsableLBA <= PrimaryHeader->PartitionEntryLBA) { -+ DEBUG ((DEBUG_ERROR, "GPT PartitionEntryLBA is not less than FirstUsableLBA!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // Check that the PartitionEntryLBA greater than the Max LBA -+ // This will be used later for multiplication -+ // -+ if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->Media->BlockSize)) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // Check that the number of partition entries is greater than zero -+ // -+ if (PrimaryHeader->NumberOfPartitionEntries == 0) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory -+ // -+ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 0)) { -+ DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // This check is to prevent overflow when calculating the allocation size for the partition entries -+ // This check will be used later for multiplication -+ // -+ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ return EFI_SUCCESS; -+} -+ -+/** -+ This function will validate that the allocation size from the primary header is sane -+ It will check the following: -+ - AllocationSize does not overflow -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[out] AllocationSize -+ Pointer to the allocation size. -+ -+ @retval EFI_SUCCESS -+ The allocation size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ The allocation size is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizePrimaryHeaderAllocationSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ OUT UINT32 *AllocationSize -+ ) -+{ -+ EFI_STATUS Status; -+ -+ if (PrimaryHeader == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (AllocationSize == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Replacing logic: -+ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry; -+ // -+ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->SizeOfPartitionEntry, AllocationSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ return EFI_SUCCESS; -+} -+ -+/** -+ This function will validate that the Gpt Event Size calculated from the primary header is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ Important: This function includes the entire length of the allocated space, including -+ (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the buffer allocated with this -+ size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) -+ from the size of the buffer before hashing. -+ -+ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ @param[in] NumberOfPartition - Number of partitions. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePrimaryHeaderGptEventSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN UINTN NumberOfPartition, -+ OUT UINT32 *EventSize -+ ) -+{ -+ EFI_STATUS Status; -+ UINT32 SafeNumberOfPartitions; -+ -+ if (PrimaryHeader == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (EventSize == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // We shouldn't even attempt to perform the multiplication if the number of partitions is greater than the maximum value of UINT32 -+ // -+ Status = SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Replacing logic: -+ // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); -+ // -+ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ // -+ // Replacing logic: -+ // *EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); -+ // -+ Status = SafeUint32Add ( -+ OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, Partitions), -+ *EventSize, -+ EventSize -+ ); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTData!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ return EFI_SUCCESS; -+} -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -new file mode 100644 -index 00000000..74af8c8b ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -@@ -0,0 +1,113 @@ -+/** @file -+ This file includes the function prototypes for the sanitization functions. -+ -+ These are those functions: -+ -+ DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content -+ read is within the image buffer. -+ -+ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse -+ partition data carefully. -+ -+ Copyright (c) Microsoft Corporation.
-+ SPDX-License-Identifier: BSD-2-Clause-Patent -+ -+**/ -+ -+#ifndef DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ -+#define DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse -+ However this function will not attempt to verify the validity of the GPT partition -+ It will check the following: -+ - Signature -+ - Revision -+ - AlternateLBA -+ - FirstUsableLBA -+ - LastUsableLBA -+ - PartitionEntryLBA -+ - NumberOfPartitionEntries -+ - SizeOfPartitionEntry -+ - BlockIo -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[in] BlockIo -+ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. -+ -+ @retval EFI_SUCCESS -+ The EFI_PARTITION_TABLE_HEADER structure is valid. -+ -+ @retval EFI_INVALID_PARAMETER -+ The EFI_PARTITION_TABLE_HEADER structure is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizeEfiPartitionTableHeader ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo -+ ); -+ -+/** -+ This function will validate that the allocation size from the primary header is sane -+ It will check the following: -+ - AllocationSize does not overflow -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[out] AllocationSize -+ Pointer to the allocation size. -+ -+ @retval EFI_SUCCESS -+ The allocation size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ The allocation size is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizePrimaryHeaderAllocationSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ OUT UINT32 *AllocationSize -+ ); -+ -+/** -+ This function will validate that the Gpt Event Size calculated from the primary header is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ Important: This function includes the entire length of the allocated space, including -+ (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the buffer allocated with this -+ size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) -+ from the size of the buffer before hashing. -+ -+ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ @param[in] NumberOfPartition - Number of partitions. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePrimaryHeaderGptEventSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN UINTN NumberOfPartition, -+ OUT UINT32 *EventSize -+ ); -+ -+#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -new file mode 100644 -index 00000000..701d1b46 ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -@@ -0,0 +1,303 @@ -+/** @file -+ This file includes the unit test cases for the DxeTpm2MeasureBootLibSanitizationTest.c. -+ -+ Copyright (c) Microsoft Corporation.
-+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../DxeTpm2MeasureBootLibSanitization.h" -+ -+#define UNIT_TEST_NAME "DxeTpm2MeasureBootLibSanitizationTest" -+#define UNIT_TEST_VERSION "1.0" -+ -+#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000 -+#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 -+#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 -+ -+/** -+ This function tests the SanitizeEfiPartitionTableHeader function. -+ It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER -+ structure will not cause undefined or unexpected behavior. -+ -+ In general the TPM should still be able to measure the data, but -+ be the header should be sanitized to prevent any unexpected behavior. -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizeEfiPartitionTableHeader ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ EFI_STATUS Status; -+ EFI_PARTITION_TABLE_HEADER PrimaryHeader; -+ EFI_BLOCK_IO_PROTOCOL BlockIo; -+ EFI_BLOCK_IO_MEDIA BlockMedia; -+ -+ // Generate EFI_BLOCK_IO_MEDIA test data -+ BlockMedia.MediaId = 1; -+ BlockMedia.RemovableMedia = FALSE; -+ BlockMedia.MediaPresent = TRUE; -+ BlockMedia.LogicalPartition = FALSE; -+ BlockMedia.ReadOnly = FALSE; -+ BlockMedia.WriteCaching = FALSE; -+ BlockMedia.BlockSize = 512; -+ BlockMedia.IoAlign = 1; -+ BlockMedia.LastBlock = 0; -+ -+ // Generate EFI_BLOCK_IO_PROTOCOL test data -+ BlockIo.Revision = 1; -+ BlockIo.Media = &BlockMedia; -+ BlockIo.Reset = NULL; -+ BlockIo.ReadBlocks = NULL; -+ BlockIo.WriteBlocks = NULL; -+ BlockIo.FlushBlocks = NULL; -+ -+ // Geneate EFI_PARTITION_TABLE_HEADER test data -+ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID; -+ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; -+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); -+ PrimaryHeader.MyLBA = 1; -+ PrimaryHeader.AlternateLBA = 2; -+ PrimaryHeader.FirstUsableLBA = 3; -+ PrimaryHeader.LastUsableLBA = 4; -+ PrimaryHeader.PartitionEntryLBA = 5; -+ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; -+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid -+ -+ // Calculate the CRC32 of the PrimaryHeader -+ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); -+ -+ // Test that a normal PrimaryHeader passes validation -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_NOT_EFI_ERROR (Status); -+ -+ // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR -+ // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" -+ PrimaryHeader.NumberOfPartitionEntries = 0; -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); -+ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ -+ // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR -+ // Should print "Invalid Partition Table Header Size!" -+ PrimaryHeader.Header.HeaderSize = 0; -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); -+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); -+ -+ // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR -+ // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" -+ PrimaryHeader.SizeOfPartitionEntry = 1; -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); -+ -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ -+ return UNIT_TEST_PASSED; -+} -+ -+/** -+ This function tests the SanitizePrimaryHeaderAllocationSize function. -+ It's intent is to test that the untrusted input from a EFI_PARTITION_TABLE_HEADER -+ structure will not cause an overflow when calculating the allocation size. -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizePrimaryHeaderAllocationSize ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ UINT32 AllocationSize; -+ -+ EFI_STATUS Status; -+ EFI_PARTITION_TABLE_HEADER PrimaryHeader; -+ -+ // Test that a normal PrimaryHeader passes validation -+ PrimaryHeader.NumberOfPartitionEntries = 5; -+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_NOT_EFI_ERROR (Status); -+ -+ // Test that the allocation size is correct compared to the existing logic -+ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry); -+ -+ // Test that an overflow is detected -+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; -+ PrimaryHeader.SizeOfPartitionEntry = 5; -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ // Test the inverse -+ PrimaryHeader.NumberOfPartitionEntries = 5; -+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ // Test the worst case scenario -+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; -+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ -+ return UNIT_TEST_PASSED; -+} -+ -+/** -+ This function tests the SanitizePrimaryHeaderGptEventSize function. -+ It's intent is to test that the untrusted input from a EFI_GPT_DATA structure -+ will not cause an overflow when calculating the event size. -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizePrimaryHeaderGptEventSize ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ UINT32 EventSize; -+ UINT32 ExistingLogicEventSize; -+ EFI_STATUS Status; -+ EFI_PARTITION_TABLE_HEADER PrimaryHeader; -+ UINTN NumberOfPartition; -+ EFI_GPT_DATA *GptData; -+ EFI_TCG2_EVENT *Tcg2Event; -+ -+ Tcg2Event = NULL; -+ GptData = NULL; -+ -+ // Test that a normal PrimaryHeader passes validation -+ PrimaryHeader.NumberOfPartitionEntries = 5; -+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ -+ // set the number of partitions -+ NumberOfPartition = 13; -+ -+ // that the primary event size is correct -+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ UT_ASSERT_NOT_EFI_ERROR (Status); -+ -+ // Calculate the existing logic event size -+ ExistingLogicEventSize = (UINT32)(OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, Partitions) -+ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); -+ -+ // Check that the event size is correct -+ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); -+ -+ // Tests that the primary event size may not overflow -+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ // Test that the size of partition entries may not overflow -+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ -+ return UNIT_TEST_PASSED; -+} -+ -+// *--------------------------------------------------------------------* -+// * Unit Test Code Main Function -+// *--------------------------------------------------------------------* -+ -+/** -+ This function acts as the entry point for the unit tests. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+ @retval others The test failed. -+**/ -+EFI_STATUS -+EFIAPI -+UefiTestMain ( -+ VOID -+ ) -+{ -+ EFI_STATUS Status; -+ UNIT_TEST_FRAMEWORK_HANDLE Framework; -+ UNIT_TEST_SUITE_HANDLE Tcg2MeasureBootLibValidationTestSuite; -+ -+ Framework = NULL; -+ -+ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); -+ -+ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status)); -+ goto EXIT; -+ } -+ -+ Status = CreateUnitTestSuite (&Tcg2MeasureBootLibValidationTestSuite, Framework, "Tcg2MeasureBootLibValidationTestSuite", "Common.Tcg2MeasureBootLibValidation", NULL, NULL); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for Tcg2MeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME)); -+ Status = EFI_OUT_OF_RESOURCES; -+ goto EXIT; -+ } -+ -+ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context -+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); -+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); -+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); -+ -+ Status = RunAllTestSuites (Framework); -+ -+EXIT: -+ if (Framework != NULL) { -+ FreeUnitTestFramework (Framework); -+ } -+ -+ DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); -+ return Status; -+} -+ -+/// -+/// Avoid ECC error for function name that starts with lower case letter -+/// -+#define DxeTpm2MeasureBootLibUnitTestMain main -+ -+/** -+ Standard POSIX C entry point for host based unit test execution. -+ -+ @param[in] Argc Number of arguments -+ @param[in] Argv Array of pointers to arguments -+ -+ @retval 0 Success -+ @retval other Error -+**/ -+INT32 -+DxeTpm2MeasureBootLibUnitTestMain ( -+ IN INT32 Argc, -+ IN CHAR8 *Argv[] -+ ) -+{ -+ return (INT32)UefiTestMain (); -+} -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf -new file mode 100644 -index 00000000..4ea55787 ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf -@@ -0,0 +1,28 @@ -+## @file -+# This file builds the unit tests for DxeTpm2MeasureBootLib -+# -+# Copyright (C) Microsoft Corporation.
-+# SPDX-License-Identifier: BSD-2-Clause-Patent -+## -+ -+[Defines] -+ INF_VERSION = 0x00010006 -+ BASE_NAME = DxeTpm2MeasuredBootLibTest -+ FILE_GUID = 144d757f-d423-484e-9309-a23695fad5bd -+ MODULE_TYPE = HOST_APPLICATION -+ VERSION_STRING = 1.0 -+ ENTRY_POINT = main -+ -+[Sources] -+ DxeTpm2MeasureBootLibSanitizationTest.c -+ ../DxeTpm2MeasureBootLibSanitization.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ -+[LibraryClasses] -+ BaseLib -+ DebugLib -+ UnitTestLib -+ PrintLib -+ SafeIntLib -diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml -index 2138b0a5..97137406 100644 ---- a/SecurityPkg/SecurityPkg.ci.yaml -+++ b/SecurityPkg/SecurityPkg.ci.yaml -@@ -16,6 +16,7 @@ - ## ] - "ExceptionList": [ - "8005", "gRT", -+ "8001", "DxeTpm2MeasureBootLibUnitTestMain", - ], - ## Both file path and directory path are accepted. - "IgnoreFiles": [ -diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc -index ad5b4fc3..57ab3af0 100644 ---- a/SecurityPkg/Test/SecurityPkgHostTest.dsc -+++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc -@@ -26,6 +26,7 @@ - SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf - SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf - SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf -+ SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf - - # - # Build SecurityPkg HOST_APPLICATION Tests --- -2.33.0 - diff --git a/0013-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch b/0013-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch deleted file mode 100644 index 796732c6fbff146671e57a0ce39b4ec8eae219bb..0000000000000000000000000000000000000000 --- a/0013-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch +++ /dev/null @@ -1,899 +0,0 @@ -From 2918cc8f6e594b7afc5c0304f7da057c69b08528 Mon Sep 17 00:00:00 2001 -From: "Douglas Flick [MSFT]" -Date: Fri, 12 Jan 2024 02:16:02 +0800 -Subject: [PATCH 02/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4117 - - CVE 2022-36763 - -This commit contains the patch files and tests for DxeTpmMeasureBootLib -CVE 2022-36763. - -Cc: Jiewen Yao - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Jiewen Yao - -reference: https://github.com/tianocore/edk2/pull/5264 -Signed-off-by: yexiao ---- - .../DxeTpmMeasureBootLib.c | 40 ++- - .../DxeTpmMeasureBootLib.inf | 4 +- - .../DxeTpmMeasureBootLibSanitization.c | 241 ++++++++++++++ - .../DxeTpmMeasureBootLibSanitization.h | 114 +++++++ - .../DxeTpmMeasureBootLibSanitizationTest.c | 301 ++++++++++++++++++ - ...eTpmMeasureBootLibSanitizationTestHost.inf | 28 ++ - SecurityPkg/SecurityPkg.ci.yaml | 1 + - SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 + - 8 files changed, 716 insertions(+), 14 deletions(-) - create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c - create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h - create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c - create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf - -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -index 220393dd..f31b49f8 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -@@ -18,6 +18,8 @@ - Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -+Copyright (c) Microsoft Corporation.
-+SPDX-License-Identifier: BSD-2-Clause-Patent - **/ - - #include -@@ -40,6 +42,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - #include - #include - -+#include "DxeTpmMeasureBootLibSanitization.h" -+ - // - // Flag to check GPT partition. It only need be measured once. - // -@@ -136,6 +140,9 @@ TcgMeasureGptTable ( - UINT32 EventSize; - UINT32 EventNumber; - EFI_PHYSICAL_ADDRESS EventLogLastEntry; -+ UINT32 AllocSize; -+ -+ GptData = NULL; - - if (mMeasureGptCount > 0) { - return EFI_SUCCESS; -@@ -166,8 +173,8 @@ TcgMeasureGptTable ( - BlockIo->Media->BlockSize, - (UINT8 *)PrimaryHeader - ); -- if (EFI_ERROR (Status)) { -- DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); -+ if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { -+ DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); - FreePool (PrimaryHeader); - return EFI_DEVICE_ERROR; - } -@@ -175,7 +182,13 @@ TcgMeasureGptTable ( - // - // Read the partition entry. - // -- EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); -+ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); -+ if (EFI_ERROR (Status)) { -+ FreePool (PrimaryHeader); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ EntryPtr = (UINT8 *)AllocatePool (AllocSize); - if (EntryPtr == NULL) { - FreePool (PrimaryHeader); - return EFI_OUT_OF_RESOURCES; -@@ -185,7 +198,7 @@ TcgMeasureGptTable ( - DiskIo, - BlockIo->Media->MediaId, - MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), -- PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, -+ AllocSize, - EntryPtr - ); - if (EFI_ERROR (Status)) { -@@ -210,9 +223,8 @@ TcgMeasureGptTable ( - // - // Prepare Data for Measurement - // -- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) -- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); -- TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT_HDR)); -+ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); -+ TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize); - if (TcgEvent == NULL) { - FreePool (PrimaryHeader); - FreePool (EntryPtr); -@@ -221,7 +233,7 @@ TcgMeasureGptTable ( - - TcgEvent->PCRIndex = 5; - TcgEvent->EventType = EV_EFI_GPT_EVENT; -- TcgEvent->EventSize = EventSize; -+ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR); - GptData = (EFI_GPT_DATA *)TcgEvent->Event; - - // -@@ -361,11 +373,13 @@ TcgMeasurePeImage ( - TcgEvent->PCRIndex = 2; - break; - default: -- DEBUG (( -- DEBUG_ERROR, -- "TcgMeasurePeImage: Unknown subsystem type %d", -- ImageType -- )); -+ DEBUG ( -+ ( -+ DEBUG_ERROR, -+ "TcgMeasurePeImage: Unknown subsystem type %d", -+ ImageType -+ ) -+ ); - goto Finish; - } - -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf -index ebab6f7c..21bfd570 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf -@@ -32,6 +32,8 @@ - - [Sources] - DxeTpmMeasureBootLib.c -+ DxeTpmMeasureBootLibSanitization.c -+ DxeTpmMeasureBootLibSanitization.h - - [Packages] - MdePkg/MdePkg.dec -@@ -41,6 +43,7 @@ - - [LibraryClasses] - BaseMemoryLib -+ SafeIntLib - DebugLib - MemoryAllocationLib - DevicePathLib -@@ -59,4 +62,3 @@ - gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES - gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES -- -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -new file mode 100644 -index 00000000..e009ce46 ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -@@ -0,0 +1,241 @@ -+/** @file -+ The library instance provides security service of TPM2 measure boot and -+ Confidential Computing (CC) measure boot. -+ -+ Caution: This file requires additional review when modified. -+ This library will have external input - PE/COFF image and GPT partition. -+ This external input must be validated carefully to avoid security issue like -+ buffer overflow, integer overflow. -+ -+ This file will pull out the validation logic from the following functions, in an -+ attempt to validate the untrusted input in the form of unit tests -+ -+ These are those functions: -+ -+ DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content -+ read is within the image buffer. -+ -+ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse -+ partition data carefully. -+ -+ Copyright (c) Microsoft Corporation.
-+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "DxeTpmMeasureBootLibSanitization.h" -+ -+#define GPT_HEADER_REVISION_V1 0x00010000 -+ -+/** -+ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse -+ However this function will not attempt to verify the validity of the GPT partition -+ It will check the following: -+ - Signature -+ - Revision -+ - AlternateLBA -+ - FirstUsableLBA -+ - LastUsableLBA -+ - PartitionEntryLBA -+ - NumberOfPartitionEntries -+ - SizeOfPartitionEntry -+ - BlockIo -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[in] BlockIo -+ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. -+ -+ @retval EFI_SUCCESS -+ The EFI_PARTITION_TABLE_HEADER structure is valid. -+ -+ @retval EFI_INVALID_PARAMETER -+ The EFI_PARTITION_TABLE_HEADER structure is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizeEfiPartitionTableHeader ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo -+ ) -+{ -+ // Verify that the input parameters are safe to use -+ if (PrimaryHeader == NULL) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if ((BlockIo == NULL) || (BlockIo->Media == NULL)) { -+ DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) -+ if (PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // The version must be GPT_HEADER_REVISION_V1 (0x00010000) -+ if (PrimaryHeader->Header.Revision != GPT_HEADER_REVISION_V1) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size -+ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // check that the PartitionEntryLBA greater than the Max LBA -+ // This will be used later for multiplication -+ if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->Media->BlockSize)) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // Check that the number of partition entries is greater than zero -+ if (PrimaryHeader->NumberOfPartitionEntries == 0) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory -+ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 0)) { -+ DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // This check is to prevent overflow when calculating the allocation size for the partition entries -+ // This check will be used later for multiplication -+ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) { -+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ return EFI_SUCCESS; -+} -+ -+/** -+ This function will validate that the allocation size from the primary header is sane -+ It will check the following: -+ - AllocationSize does not overflow -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[out] AllocationSize -+ Pointer to the allocation size. -+ -+ @retval EFI_SUCCESS -+ The allocation size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ The allocation size is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizePrimaryHeaderAllocationSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ OUT UINT32 *AllocationSize -+ ) -+{ -+ EFI_STATUS Status; -+ -+ if (PrimaryHeader == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (AllocationSize == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // Replacing logic: -+ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry; -+ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->SizeOfPartitionEntry, AllocationSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ return EFI_SUCCESS; -+} -+ -+/** -+ This function will validate that the Gpt Event Size calculated from the primary header is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ Important: This function includes the entire length of the allocated space, including the -+ TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the caller must subtract -+ the size of the TCG_PCR_EVENT_HDR from the size of the buffer before hashing. -+ -+ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ @param[in] NumberOfPartition - Number of partitions. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePrimaryHeaderGptEventSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN UINTN NumberOfPartition, -+ OUT UINT32 *EventSize -+ ) -+{ -+ EFI_STATUS Status; -+ UINT32 SafeNumberOfPartitions; -+ -+ if (PrimaryHeader == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (EventSize == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // We shouldn't even attempt to perform the multiplication if the number of partitions is greater than the maximum value of UINT32 -+ Status = SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // Replacing logic: -+ // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry + sizeof (TCG_PCR_EVENT_HDR)); -+ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ Status = SafeUint32Add ( -+ sizeof (TCG_PCR_EVENT_HDR) + -+ OFFSET_OF (EFI_GPT_DATA, Partitions), -+ *EventSize, -+ EventSize -+ ); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTData!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ return EFI_SUCCESS; -+} -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -new file mode 100644 -index 00000000..57e05e48 ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -@@ -0,0 +1,114 @@ -+/** @file -+ This file includes the function prototypes for the sanitization functions. -+ -+ These are those functions: -+ -+ DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content -+ read is within the image buffer. -+ -+ TcgMeasurePeImage() function will accept untrusted PE/COFF image and validate its -+ data structure within this image buffer before use. -+ -+ TcgMeasureGptTable() function will receive untrusted GPT partition table, and parse -+ partition data carefully. -+ -+ Copyright (c) Microsoft Corporation.
-+ SPDX-License-Identifier: BSD-2-Clause-Patent -+ -+**/ -+ -+#ifndef DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ -+#define DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ -+ -+#include -+#include -+#include -+#include -+ -+/** -+ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse -+ However this function will not attempt to verify the validity of the GPT partition -+ It will check the following: -+ - Signature -+ - Revision -+ - AlternateLBA -+ - FirstUsableLBA -+ - LastUsableLBA -+ - PartitionEntryLBA -+ - NumberOfPartitionEntries -+ - SizeOfPartitionEntry -+ - BlockIo -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[in] BlockIo -+ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. -+ -+ @retval EFI_SUCCESS -+ The EFI_PARTITION_TABLE_HEADER structure is valid. -+ -+ @retval EFI_INVALID_PARAMETER -+ The EFI_PARTITION_TABLE_HEADER structure is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizeEfiPartitionTableHeader ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo -+ ); -+ -+/** -+ This function will validate that the allocation size from the primary header is sane -+ It will check the following: -+ - AllocationSize does not overflow -+ -+ @param[in] PrimaryHeader -+ Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ -+ @param[out] AllocationSize -+ Pointer to the allocation size. -+ -+ @retval EFI_SUCCESS -+ The allocation size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ The allocation size is invalid. -+**/ -+EFI_STATUS -+EFIAPI -+SanitizePrimaryHeaderAllocationSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ OUT UINT32 *AllocationSize -+ ); -+ -+/** -+ This function will validate that the Gpt Event Size calculated from the primary header is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ Important: This function includes the entire length of the allocated space, including the -+ TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the caller must subtract -+ the size of the TCG_PCR_EVENT_HDR from the size of the buffer before hashing. -+ -+ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. -+ @param[in] NumberOfPartition - Number of partitions. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePrimaryHeaderGptEventSize ( -+ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, -+ IN UINTN NumberOfPartition, -+ OUT UINT32 *EventSize -+ ); -+ -+#endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -new file mode 100644 -index 00000000..8cd97480 ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -@@ -0,0 +1,301 @@ -+/** @file -+This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. -+ -+Copyright (c) Microsoft Corporation.
-+SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../DxeTpmMeasureBootLibSanitization.h" -+ -+#define UNIT_TEST_NAME "DxeTpmMeasureBootLibSanitizationTest" -+#define UNIT_TEST_VERSION "1.0" -+ -+#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000 -+#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 -+#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 -+ -+/** -+ This function tests the SanitizeEfiPartitionTableHeader function. -+ It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER -+ structure will not cause undefined or unexpected behavior. -+ -+ In general the TPM should still be able to measure the data, but -+ be the header should be sanitized to prevent any unexpected behavior. -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizeEfiPartitionTableHeader ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ EFI_STATUS Status; -+ EFI_PARTITION_TABLE_HEADER PrimaryHeader; -+ EFI_BLOCK_IO_PROTOCOL BlockIo; -+ EFI_BLOCK_IO_MEDIA BlockMedia; -+ -+ // Generate EFI_BLOCK_IO_MEDIA test data -+ BlockMedia.MediaId = 1; -+ BlockMedia.RemovableMedia = FALSE; -+ BlockMedia.MediaPresent = TRUE; -+ BlockMedia.LogicalPartition = FALSE; -+ BlockMedia.ReadOnly = FALSE; -+ BlockMedia.WriteCaching = FALSE; -+ BlockMedia.BlockSize = 512; -+ BlockMedia.IoAlign = 1; -+ BlockMedia.LastBlock = 0; -+ -+ // Generate EFI_BLOCK_IO_PROTOCOL test data -+ BlockIo.Revision = 1; -+ BlockIo.Media = &BlockMedia; -+ BlockIo.Reset = NULL; -+ BlockIo.ReadBlocks = NULL; -+ BlockIo.WriteBlocks = NULL; -+ BlockIo.FlushBlocks = NULL; -+ -+ // Geneate EFI_PARTITION_TABLE_HEADER test data -+ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID; -+ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; -+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); -+ PrimaryHeader.MyLBA = 1; -+ PrimaryHeader.AlternateLBA = 2; -+ PrimaryHeader.FirstUsableLBA = 3; -+ PrimaryHeader.LastUsableLBA = 4; -+ PrimaryHeader.PartitionEntryLBA = 5; -+ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; -+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid -+ -+ // Calculate the CRC32 of the PrimaryHeader -+ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); -+ -+ // Test that a normal PrimaryHeader passes validation -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_NOT_EFI_ERROR (Status); -+ -+ // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR -+ // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" -+ PrimaryHeader.NumberOfPartitionEntries = 0; -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); -+ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ -+ // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR -+ // Should print "Invalid Partition Table Header Size!" -+ PrimaryHeader.Header.HeaderSize = 0; -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); -+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); -+ -+ // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR -+ // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" -+ PrimaryHeader.SizeOfPartitionEntry = 1; -+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); -+ -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ -+ return UNIT_TEST_PASSED; -+} -+ -+/** -+ This function tests the SanitizePrimaryHeaderAllocationSize function. -+ It's intent is to test that the untrusted input from a EFI_PARTITION_TABLE_HEADER -+ structure will not cause an overflow when calculating the allocation size. -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizePrimaryHeaderAllocationSize ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ UINT32 AllocationSize; -+ -+ EFI_STATUS Status; -+ EFI_PARTITION_TABLE_HEADER PrimaryHeader; -+ -+ // Test that a normal PrimaryHeader passes validation -+ PrimaryHeader.NumberOfPartitionEntries = 5; -+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_NOT_EFI_ERROR (Status); -+ -+ // Test that the allocation size is correct compared to the existing logic -+ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry); -+ -+ // Test that an overflow is detected -+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; -+ PrimaryHeader.SizeOfPartitionEntry = 5; -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ // Test the inverse -+ PrimaryHeader.NumberOfPartitionEntries = 5; -+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ // Test the worst case scenario -+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; -+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ -+ return UNIT_TEST_PASSED; -+} -+ -+/** -+ This function tests the SanitizePrimaryHeaderGptEventSize function. -+ It's intent is to test that the untrusted input from a EFI_GPT_DATA structure -+ will not cause an overflow when calculating the event size. -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizePrimaryHeaderGptEventSize ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ UINT32 EventSize; -+ UINT32 ExistingLogicEventSize; -+ EFI_STATUS Status; -+ EFI_PARTITION_TABLE_HEADER PrimaryHeader; -+ UINTN NumberOfPartition; -+ EFI_GPT_DATA *GptData; -+ -+ GptData = NULL; -+ -+ // Test that a normal PrimaryHeader passes validation -+ PrimaryHeader.NumberOfPartitionEntries = 5; -+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; -+ -+ // set the number of partitions -+ NumberOfPartition = 13; -+ -+ // that the primary event size is correct -+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ UT_ASSERT_NOT_EFI_ERROR (Status); -+ -+ // Calculate the existing logic event size -+ ExistingLogicEventSize = (UINT32)(sizeof (TCG_PCR_EVENT_HDR) + OFFSET_OF (EFI_GPT_DATA, Partitions) -+ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); -+ -+ // Check that the event size is correct -+ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); -+ -+ // Tests that the primary event size may not overflow -+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ // Test that the size of partition entries may not overflow -+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ -+ return UNIT_TEST_PASSED; -+} -+ -+// *--------------------------------------------------------------------* -+// * Unit Test Code Main Function -+// *--------------------------------------------------------------------* -+ -+/** -+ This function acts as the entry point for the unit tests. -+ -+ @param argc - The number of command line arguments -+ @param argv - The command line arguments -+ -+ @return int - The status of the test -+**/ -+EFI_STATUS -+EFIAPI -+UefiTestMain ( -+ VOID -+ ) -+{ -+ EFI_STATUS Status; -+ UNIT_TEST_FRAMEWORK_HANDLE Framework; -+ UNIT_TEST_SUITE_HANDLE TcgMeasureBootLibValidationTestSuite; -+ -+ Framework = NULL; -+ -+ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); -+ -+ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status)); -+ goto EXIT; -+ } -+ -+ Status = CreateUnitTestSuite (&TcgMeasureBootLibValidationTestSuite, Framework, "TcgMeasureBootLibValidationTestSuite", "Common.TcgMeasureBootLibValidation", NULL, NULL); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for TcgMeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME)); -+ Status = EFI_OUT_OF_RESOURCES; -+ goto EXIT; -+ } -+ -+ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context -+ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); -+ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); -+ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); -+ -+ Status = RunAllTestSuites (Framework); -+ -+EXIT: -+ if (Framework != NULL) { -+ FreeUnitTestFramework (Framework); -+ } -+ -+ DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); -+ return Status; -+} -+ -+/// -+/// Avoid ECC error for function name that starts with lower case letter -+/// -+#define DxeTpmMeasureBootLibUnitTestMain main -+ -+/** -+ Standard POSIX C entry point for host based unit test execution. -+ -+ @param[in] Argc Number of arguments -+ @param[in] Argv Array of pointers to arguments -+ -+ @retval 0 Success -+ @retval other Error -+**/ -+INT32 -+DxeTpmMeasureBootLibUnitTestMain ( -+ IN INT32 Argc, -+ IN CHAR8 *Argv[] -+ ) -+{ -+ return (INT32)UefiTestMain (); -+} -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf -new file mode 100644 -index 00000000..ba4c58cb ---- /dev/null -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf -@@ -0,0 +1,28 @@ -+## @file -+# This file builds the unit tests for DxeTpmMeasureBootLib -+# -+# Copyright (C) Microsoft Corporation.
-+# SPDX-License-Identifier: BSD-2-Clause-Patent -+## -+ -+[Defines] -+ INF_VERSION = 0x00010006 -+ BASE_NAME = DxeTpmMeasuredBootLibTest -+ FILE_GUID = eb01bc38-309c-4d3e-967e-9f078c90772f -+ MODULE_TYPE = HOST_APPLICATION -+ VERSION_STRING = 1.0 -+ ENTRY_POINT = main -+ -+[Sources] -+ DxeTpmMeasureBootLibSanitizationTest.c -+ ../DxeTpmMeasureBootLibSanitization.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ -+[LibraryClasses] -+ BaseLib -+ DebugLib -+ UnitTestLib -+ PrintLib -+ SafeIntLib -diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml -index 97137406..c6716cb1 100644 ---- a/SecurityPkg/SecurityPkg.ci.yaml -+++ b/SecurityPkg/SecurityPkg.ci.yaml -@@ -17,6 +17,7 @@ - "ExceptionList": [ - "8005", "gRT", - "8001", "DxeTpm2MeasureBootLibUnitTestMain", -+ "8001", "DxeTpmMeasureBootLibUnitTestMain" - ], - ## Both file path and directory path are accepted. - "IgnoreFiles": [ -diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc -index 57ab3af0..470bba07 100644 ---- a/SecurityPkg/Test/SecurityPkgHostTest.dsc -+++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc -@@ -27,6 +27,7 @@ - SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf - SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf - SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf -+ SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf - - # - # Build SecurityPkg HOST_APPLICATION Tests --- -2.33.0 - diff --git a/0014-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch b/0014-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch deleted file mode 100644 index 091c37b3533a16062c4c3c63ff0986804b479791..0000000000000000000000000000000000000000 --- a/0014-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 44c29a76c7bba325ba55b41811e5bbe22d1552a7 Mon Sep 17 00:00:00 2001 -From: "Douglas Flick [MSFT]" -Date: Fri, 12 Jan 2024 02:16:03 +0800 -Subject: [PATCH 03/10] SecurityPkg: : Adding CVE 2022-36763 to - SecurityFixes.yaml - -This creates / adds a security file that tracks the security fixes -found in this package and can be used to find the fixes that were -applied. - -Cc: Jiewen Yao - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Jiewen Yao - -reference: https://github.com/tianocore/edk2/pull/5264 -Signed-off-by: yexiao ---- - SecurityPkg/SecurityFixes.yaml | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - create mode 100644 SecurityPkg/SecurityFixes.yaml - -diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml -new file mode 100644 -index 00000000..36ac267e ---- /dev/null -+++ b/SecurityPkg/SecurityFixes.yaml -@@ -0,0 +1,22 @@ -+## @file -+# Security Fixes for SecurityPkg -+# -+# Copyright (c) Microsoft Corporation -+# SPDX-License-Identifier: BSD-2-Clause-Patent -+## -+CVE_2022_36763: -+ commit_titles: -+ - "SecurityPkg: DxeTpm2Measurement: SECURITY PATCH 4117 - CVE 2022-36763" -+ - "SecurityPkg: DxeTpmMeasurement: SECURITY PATCH 4117 - CVE 2022-36763" -+ - "SecurityPkg: : Adding CVE 2022-36763 to SecurityFixes.yaml" -+ cve: CVE-2022-36763 -+ date_reported: 2022-10-25 11:31 UTC -+ description: (CVE-2022-36763) - Heap Buffer Overflow in Tcg2MeasureGptTable() -+ note: This patch is related to and supersedes TCBZ2168 -+ files_impacted: -+ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c -+ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 --- -2.33.0 - diff --git a/0015-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch b/0015-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch deleted file mode 100644 index 64c7aa6675213947af2e9769f62e3fed4fdab35a..0000000000000000000000000000000000000000 --- a/0015-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 820c5c78a73729f720c76345f185ca46e190cf02 Mon Sep 17 00:00:00 2001 -From: "Douglas Flick [MSFT]" -Date: Fri, 12 Jan 2024 02:16:04 +0800 -Subject: [PATCH 04/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - - CVE 2022-36764 - -This commit contains the patch files and tests for DxeTpm2MeasureBootLib -CVE 2022-36764. - -Cc: Jiewen Yao - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Jiewen Yao - -reference: https://github.com/tianocore/edk2/pull/5264 -Signed-off-by: yexiao ---- - .../DxeTpm2MeasureBootLib.c | 12 ++-- - .../DxeTpm2MeasureBootLibSanitization.c | 46 +++++++++++++- - .../DxeTpm2MeasureBootLibSanitization.h | 28 ++++++++- - .../DxeTpm2MeasureBootLibSanitizationTest.c | 60 ++++++++++++++++--- - 4 files changed, 131 insertions(+), 15 deletions(-) - -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -index 0a37a4b6..ffab7968 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -@@ -378,7 +378,6 @@ Exit: - @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. - @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is mal-format. - @retval other error value -- - **/ - EFI_STATUS - EFIAPI -@@ -405,6 +404,7 @@ Tcg2MeasurePeImage ( - Status = EFI_UNSUPPORTED; - ImageLoad = NULL; - EventPtr = NULL; -+ Tcg2Event = NULL; - - Tcg2Protocol = MeasureBootProtocols->Tcg2Protocol; - CcProtocol = MeasureBootProtocols->CcProtocol; -@@ -420,18 +420,22 @@ Tcg2MeasurePeImage ( - } - - FilePathSize = (UINT32)GetDevicePathSize (FilePath); -+ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ if (EFI_ERROR (Status)) { -+ return EFI_UNSUPPORTED; -+ } - - // - // Determine destination PCR by BootPolicy - // -- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; -- EventPtr = AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)); -+ // from a malicious GPT disk partition -+ EventPtr = AllocateZeroPool (EventSize); - if (EventPtr == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Tcg2Event = (EFI_TCG2_EVENT *)EventPtr; -- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); -+ Tcg2Event->Size = EventSize; - Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); - Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION; - ImageLoad = (EFI_IMAGE_LOAD_EVENT *)Tcg2Event->Event; -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -index ef3b77b4..bc583c97 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -@@ -151,7 +151,7 @@ SanitizeEfiPartitionTableHeader ( - } - - /** -- This function will validate that the allocation size from the primary header is sane -+ This function will validate that the allocation size from the primary header is sane - It will check the following: - - AllocationSize does not overflow - -@@ -273,3 +273,47 @@ SanitizePrimaryHeaderGptEventSize ( - - return EFI_SUCCESS; - } -+ -+/** -+ This function will validate that the PeImage Event Size from the loaded image is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ @param[in] FilePathSize - Size of the file path. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePeImageEventSize ( -+ IN UINT32 FilePathSize, -+ OUT UINT32 *EventSize -+ ) -+{ -+ EFI_STATUS Status; -+ -+ // Replacing logic: -+ // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; -+ Status = SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), FilePathSize, EventSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ // Replacing logic: -+ // EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event) -+ Status = SafeUint32Add (*EventSize, OFFSET_OF (EFI_TCG2_EVENT, Event), EventSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ return EFI_SUCCESS; -+} -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -index 74af8c8b..bfbfb589 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -@@ -9,6 +9,9 @@ - Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse - partition data carefully. - -+ Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and validate its -+ data structure within this image buffer before use. -+ - Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -@@ -110,4 +113,27 @@ SanitizePrimaryHeaderGptEventSize ( - OUT UINT32 *EventSize - ); - --#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ -+/** -+ This function will validate that the PeImage Event Size from the loaded image is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ @param[in] FilePathSize - Size of the file path. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePeImageEventSize ( -+ IN UINT32 FilePathSize, -+ OUT UINT32 *EventSize -+ ); -+ -+#endif // DXE_TPM2_MEASURE_BOOT_LIB_VALIDATION_ -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -index 701d1b46..8d8c0b26 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -@@ -72,10 +72,10 @@ TestSanitizeEfiPartitionTableHeader ( - PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; - PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); - PrimaryHeader.MyLBA = 1; -- PrimaryHeader.AlternateLBA = 2; -- PrimaryHeader.FirstUsableLBA = 3; -- PrimaryHeader.LastUsableLBA = 4; -- PrimaryHeader.PartitionEntryLBA = 5; -+ PrimaryHeader.PartitionEntryLBA = 2; -+ PrimaryHeader.AlternateLBA = 3; -+ PrimaryHeader.FirstUsableLBA = 4; -+ PrimaryHeader.LastUsableLBA = 5; - PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; - PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; - PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid -@@ -187,11 +187,6 @@ TestSanitizePrimaryHeaderGptEventSize ( - EFI_STATUS Status; - EFI_PARTITION_TABLE_HEADER PrimaryHeader; - UINTN NumberOfPartition; -- EFI_GPT_DATA *GptData; -- EFI_TCG2_EVENT *Tcg2Event; -- -- Tcg2Event = NULL; -- GptData = NULL; - - // Test that a normal PrimaryHeader passes validation - PrimaryHeader.NumberOfPartitionEntries = 5; -@@ -225,6 +220,52 @@ TestSanitizePrimaryHeaderGptEventSize ( - return UNIT_TEST_PASSED; - } - -+/** -+ This function tests the SanitizePeImageEventSize function. -+ It's intent is to test that the untrusted input from a file path when generating a -+ EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculating -+ the event size when allocating space -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizePeImageEventSize ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ UINT32 EventSize; -+ UINTN ExistingLogicEventSize; -+ UINT32 FilePathSize; -+ EFI_STATUS Status; -+ -+ FilePathSize = 255; -+ -+ // Test that a normal PE image passes validation -+ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ UT_ASSERT_EQUAL (Status, EFI_SUCCESS); -+ -+ // Test that the event size is correct compared to the existing logic -+ ExistingLogicEventSize = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize; -+ ExistingLogicEventSize += OFFSET_OF (EFI_TCG2_EVENT, Event); -+ -+ if (EventSize != ExistingLogicEventSize) { -+ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); -+ return UNIT_TEST_ERROR_TEST_FAILED; -+ } -+ -+ // Test that the event size may not overflow -+ Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); -+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); -+ -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ -+ return UNIT_TEST_PASSED; -+} -+ - // *--------------------------------------------------------------------* - // * Unit Test Code Main Function - // *--------------------------------------------------------------------* -@@ -267,6 +308,7 @@ UefiTestMain ( - AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); - AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); - AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); -+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests PE Image and FileSize checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL); - - Status = RunAllTestSuites (Framework); - --- -2.33.0 - diff --git a/0016-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch b/0016-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch deleted file mode 100644 index 981812ba4ccbf162aab5234dcf3fbee70563c2ba..0000000000000000000000000000000000000000 --- a/0016-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 22690cad49ef3b07c2bba554eabbf9e1b631f55c Mon Sep 17 00:00:00 2001 -From: "Douglas Flick [MSFT]" -Date: Fri, 12 Jan 2024 02:16:05 +0800 -Subject: [PATCH 05/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - - CVE 2022-36764 - -This commit contains the patch files and tests for DxeTpmMeasureBootLib -CVE 2022-36764. - -Cc: Jiewen Yao - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Jiewen Yao - -reference: https://github.com/tianocore/edk2/pull/5264 -Signed-off-by: yexiao ---- - .../DxeTpmMeasureBootLib.c | 13 ++- - .../DxeTpmMeasureBootLibSanitization.c | 44 +++++++++ - .../DxeTpmMeasureBootLibSanitization.h | 23 +++++ - .../DxeTpmMeasureBootLibSanitizationTest.c | 98 +++++++++++++++++-- - 4 files changed, 168 insertions(+), 10 deletions(-) - -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -index f31b49f8..23329185 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -@@ -17,6 +17,7 @@ - - Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent -+Copyright (c) Microsoft Corporation.
- - Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent -@@ -345,18 +346,22 @@ TcgMeasurePeImage ( - ImageLoad = NULL; - SectionHeader = NULL; - Sha1Ctx = NULL; -+ TcgEvent = NULL; - FilePathSize = (UINT32)GetDevicePathSize (FilePath); - -- // - // Determine destination PCR by BootPolicy - // -- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; -- TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT)); -+ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ if (EFI_ERROR (Status)) { -+ return EFI_UNSUPPORTED; -+ } -+ -+ TcgEvent = AllocateZeroPool (EventSize); - if (TcgEvent == NULL) { - return EFI_OUT_OF_RESOURCES; - } - -- TcgEvent->EventSize = EventSize; -+ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR); - ImageLoad = (EFI_IMAGE_LOAD_EVENT *)TcgEvent->Event; - - switch (ImageType) { -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -index e009ce46..33a230f8 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -@@ -239,3 +239,47 @@ SanitizePrimaryHeaderGptEventSize ( - - return EFI_SUCCESS; - } -+ -+/** -+ This function will validate that the PeImage Event Size from the loaded image is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ @param[in] FilePathSize - Size of the file path. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePeImageEventSize ( -+ IN UINT32 FilePathSize, -+ OUT UINT32 *EventSize -+ ) -+{ -+ EFI_STATUS Status; -+ -+ // Replacing logic: -+ // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; -+ Status = SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), FilePathSize, EventSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ // Replacing logic: -+ // EventSize + sizeof (TCG_PCR_EVENT_HDR) -+ Status = SafeUint32Add (*EventSize, sizeof (TCG_PCR_EVENT_HDR), EventSize); -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); -+ return EFI_BAD_BUFFER_SIZE; -+ } -+ -+ return EFI_SUCCESS; -+} -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -index 57e05e48..181aba42 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -@@ -111,4 +111,27 @@ SanitizePrimaryHeaderGptEventSize ( - OUT UINT32 *EventSize - ); - -+/** -+ This function will validate that the PeImage Event Size from the loaded image is sane -+ It will check the following: -+ - EventSize does not overflow -+ -+ @param[in] FilePathSize - Size of the file path. -+ @param[out] EventSize - Pointer to the event size. -+ -+ @retval EFI_SUCCESS -+ The event size is valid. -+ -+ @retval EFI_OUT_OF_RESOURCES -+ Overflow would have occurred. -+ -+ @retval EFI_INVALID_PARAMETER -+ One of the passed parameters was invalid. -+**/ -+EFI_STATUS -+SanitizePeImageEventSize ( -+ IN UINT32 FilePathSize, -+ OUT UINT32 *EventSize -+ ); -+ - #endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -index 8cd97480..77a67826 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -@@ -1,8 +1,8 @@ - /** @file --This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. -+ This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. - --Copyright (c) Microsoft Corporation.
--SPDX-License-Identifier: BSD-2-Clause-Patent -+ Copyright (c) Microsoft Corporation.
-+ SPDX-License-Identifier: BSD-2-Clause-Patent - **/ - - #include -@@ -186,9 +186,6 @@ TestSanitizePrimaryHeaderGptEventSize ( - EFI_STATUS Status; - EFI_PARTITION_TABLE_HEADER PrimaryHeader; - UINTN NumberOfPartition; -- EFI_GPT_DATA *GptData; -- -- GptData = NULL; - - // Test that a normal PrimaryHeader passes validation - PrimaryHeader.NumberOfPartitionEntries = 5; -@@ -222,6 +219,94 @@ TestSanitizePrimaryHeaderGptEventSize ( - return UNIT_TEST_PASSED; - } - -+/** -+ This function tests the SanitizePeImageEventSize function. -+ It's intent is to test that the untrusted input from a file path for an -+ EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculating -+ the event size when allocating space. -+ -+ @param[in] Context The unit test context. -+ -+ @retval UNIT_TEST_PASSED The test passed. -+ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. -+**/ -+UNIT_TEST_STATUS -+EFIAPI -+TestSanitizePeImageEventSize ( -+ IN UNIT_TEST_CONTEXT Context -+ ) -+{ -+ UINT32 EventSize; -+ UINTN ExistingLogicEventSize; -+ UINT32 FilePathSize; -+ EFI_STATUS Status; -+ EFI_DEVICE_PATH_PROTOCOL DevicePath; -+ EFI_IMAGE_LOAD_EVENT *ImageLoadEvent; -+ UNIT_TEST_STATUS TestStatus; -+ -+ TestStatus = UNIT_TEST_ERROR_TEST_FAILED; -+ -+ // Generate EFI_DEVICE_PATH_PROTOCOL test data -+ DevicePath.Type = 0; -+ DevicePath.SubType = 0; -+ DevicePath.Length[0] = 0; -+ DevicePath.Length[1] = 0; -+ -+ // Generate EFI_IMAGE_LOAD_EVENT test data -+ ImageLoadEvent = AllocateZeroPool (sizeof (EFI_IMAGE_LOAD_EVENT) + sizeof (EFI_DEVICE_PATH_PROTOCOL)); -+ if (ImageLoadEvent == NULL) { -+ DEBUG ((DEBUG_ERROR, "%a: AllocateZeroPool failed\n", __func__)); -+ goto Exit; -+ } -+ -+ // Populate EFI_IMAGE_LOAD_EVENT54 test data -+ ImageLoadEvent->ImageLocationInMemory = (EFI_PHYSICAL_ADDRESS)0x12345678; -+ ImageLoadEvent->ImageLengthInMemory = 0x1000; -+ ImageLoadEvent->ImageLinkTimeAddress = (UINTN)ImageLoadEvent; -+ ImageLoadEvent->LengthOfDevicePath = sizeof (EFI_DEVICE_PATH_PROTOCOL); -+ CopyMem (ImageLoadEvent->DevicePath, &DevicePath, sizeof (EFI_DEVICE_PATH_PROTOCOL)); -+ -+ FilePathSize = 255; -+ -+ // Test that a normal PE image passes validation -+ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ if (EFI_ERROR (Status)) { -+ UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status); -+ goto Exit; -+ } -+ -+ // Test that the event size is correct compared to the existing logic -+ ExistingLogicEventSize = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize; -+ ExistingLogicEventSize += sizeof (TCG_PCR_EVENT_HDR); -+ -+ if (EventSize != ExistingLogicEventSize) { -+ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); -+ goto Exit; -+ } -+ -+ // Test that the event size may not overflow -+ Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); -+ if (Status != EFI_BAD_BUFFER_SIZE) { -+ UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status); -+ goto Exit; -+ } -+ -+ TestStatus = UNIT_TEST_PASSED; -+Exit: -+ -+ if (ImageLoadEvent != NULL) { -+ FreePool (ImageLoadEvent); -+ } -+ -+ if (TestStatus == UNIT_TEST_ERROR_TEST_FAILED) { -+ DEBUG ((DEBUG_ERROR, "%a: Test failed\n", __func__)); -+ } else { -+ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -+ } -+ -+ return TestStatus; -+} -+ - // *--------------------------------------------------------------------* - // * Unit Test Code Main Function - // *--------------------------------------------------------------------* -@@ -265,6 +350,7 @@ UefiTestMain ( - AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); - AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); - AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); -+ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests PE Image and FileSize checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL); - - Status = RunAllTestSuites (Framework); - --- -2.33.0 - diff --git a/0017-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch b/0017-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch deleted file mode 100644 index 51e41ab8a1bd48958d0092d3380ead86e6117062..0000000000000000000000000000000000000000 --- a/0017-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 02c99cab3ac4b61a9e274e1db7802a06e772abaf Mon Sep 17 00:00:00 2001 -From: "Douglas Flick [MSFT]" -Date: Fri, 12 Jan 2024 02:16:06 +0800 -Subject: [PATCH 06/10] SecurityPkg: : Adding CVE 2022-36764 to - SecurityFixes.yaml - -This creates / adds a security file that tracks the security fixes -found in this package and can be used to find the fixes that were -applied. - -Cc: Jiewen Yao - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Jiewen Yao - -reference: https://github.com/tianocore/edk2/pull/5264 -Signed-off-by: yexiao ---- - SecurityPkg/SecurityFixes.yaml | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml -index 36ac267e..ceaaa256 100644 ---- a/SecurityPkg/SecurityFixes.yaml -+++ b/SecurityPkg/SecurityFixes.yaml -@@ -20,3 +20,17 @@ CVE_2022_36763: - - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 - - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 - - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 -+CVE_2022_36764: -+ commit_titles: -+ - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" -+ - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" -+ - "SecurityPkg: : Adding CVE 2022-36764 to SecurityFixes.yaml" -+ cve: CVE-2022-36764 -+ date_reported: 2022-10-25 12:23 UTC -+ description: Heap Buffer Overflow in Tcg2MeasurePeImage() -+ note: -+ files_impacted: -+ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c -+ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 --- -2.33.0 - diff --git a/0018-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch b/0018-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch deleted file mode 100644 index 7b1aa4be2d5fcb8b28fe9816ce94ddc25975329e..0000000000000000000000000000000000000000 --- a/0018-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch +++ /dev/null @@ -1,257 +0,0 @@ -From bfdc271e28418b8a1b50d09112c48c371087efd1 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Wed, 17 Jan 2024 14:47:20 -0800 -Subject: [PATCH 07/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH - 4117/4118 symbol rename - -Updates the sanitation function names to be lib unique names - -Cc: Jiewen Yao -Cc: Rahul Kumar - -Signed-off-by: Doug Flick [MSFT] -Message-Id: <7b18434c8a8b561654efd40ced3becb8b378c8f1.1705529990.git.doug.edk2@gmail.com> -Reviewed-by: Jiewen Yao - -reference: https://github.com/tianocore/edk2/pull/5273 -Signed-off-by: yexiao ---- - .../DxeTpm2MeasureBootLib.c | 8 +++--- - .../DxeTpm2MeasureBootLibSanitization.c | 8 +++--- - .../DxeTpm2MeasureBootLibSanitization.h | 8 +++--- - .../DxeTpm2MeasureBootLibSanitizationTest.c | 26 +++++++++---------- - 4 files changed, 25 insertions(+), 25 deletions(-) - -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -index ffab7968..cc58b8bf 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c -@@ -200,7 +200,7 @@ Tcg2MeasureGptTable ( - BlockIo->Media->BlockSize, - (UINT8 *)PrimaryHeader - ); -- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { -+ if (EFI_ERROR (Status) || EFI_ERROR (Tpm2SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { - DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); - FreePool (PrimaryHeader); - return EFI_DEVICE_ERROR; -@@ -209,7 +209,7 @@ Tcg2MeasureGptTable ( - // - // Read the partition entry. - // -- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); -+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); - if (EFI_ERROR (Status)) { - FreePool (PrimaryHeader); - return EFI_BAD_BUFFER_SIZE; -@@ -250,7 +250,7 @@ Tcg2MeasureGptTable ( - // - // Prepare Data for Measurement (CcProtocol and Tcg2Protocol) - // -- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); -+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); - if (EFI_ERROR (Status)) { - FreePool (PrimaryHeader); - FreePool (EntryPtr); -@@ -420,7 +420,7 @@ Tcg2MeasurePeImage ( - } - - FilePathSize = (UINT32)GetDevicePathSize (FilePath); -- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -index bc583c97..d911efe6 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c -@@ -63,7 +63,7 @@ - **/ - EFI_STATUS - EFIAPI --SanitizeEfiPartitionTableHeader ( -+Tpm2SanitizeEfiPartitionTableHeader ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo - ) -@@ -169,7 +169,7 @@ SanitizeEfiPartitionTableHeader ( - **/ - EFI_STATUS - EFIAPI --SanitizePrimaryHeaderAllocationSize ( -+Tpm2SanitizePrimaryHeaderAllocationSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - OUT UINT32 *AllocationSize - ) -@@ -221,7 +221,7 @@ SanitizePrimaryHeaderAllocationSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePrimaryHeaderGptEventSize ( -+Tpm2SanitizePrimaryHeaderGptEventSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN UINTN NumberOfPartition, - OUT UINT32 *EventSize -@@ -292,7 +292,7 @@ SanitizePrimaryHeaderGptEventSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePeImageEventSize ( -+Tpm2SanitizePeImageEventSize ( - IN UINT32 FilePathSize, - OUT UINT32 *EventSize - ) -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -index bfbfb589..504958f4 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h -@@ -54,7 +54,7 @@ - **/ - EFI_STATUS - EFIAPI --SanitizeEfiPartitionTableHeader ( -+Tpm2SanitizeEfiPartitionTableHeader ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo - ); -@@ -78,7 +78,7 @@ SanitizeEfiPartitionTableHeader ( - **/ - EFI_STATUS - EFIAPI --SanitizePrimaryHeaderAllocationSize ( -+Tpm2SanitizePrimaryHeaderAllocationSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - OUT UINT32 *AllocationSize - ); -@@ -107,7 +107,7 @@ SanitizePrimaryHeaderAllocationSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePrimaryHeaderGptEventSize ( -+Tpm2SanitizePrimaryHeaderGptEventSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN UINTN NumberOfPartition, - OUT UINT32 *EventSize -@@ -131,7 +131,7 @@ SanitizePrimaryHeaderGptEventSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePeImageEventSize ( -+Tpm2SanitizePeImageEventSize ( - IN UINT32 FilePathSize, - OUT UINT32 *EventSize - ); -diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -index 8d8c0b26..0e33fec5 100644 ---- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c -@@ -84,27 +84,27 @@ TestSanitizeEfiPartitionTableHeader ( - PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); - - // Test that a normal PrimaryHeader passes validation -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR - // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" - PrimaryHeader.NumberOfPartitionEntries = 0; -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); - PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; - - // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR - // Should print "Invalid Partition Table Header Size!" - PrimaryHeader.Header.HeaderSize = 0; -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); - PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); - - // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR - // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" - PrimaryHeader.SizeOfPartitionEntry = 1; -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); - - DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -@@ -137,7 +137,7 @@ TestSanitizePrimaryHeaderAllocationSize ( - PrimaryHeader.NumberOfPartitionEntries = 5; - PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; - -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Test that the allocation size is correct compared to the existing logic -@@ -146,19 +146,19 @@ TestSanitizePrimaryHeaderAllocationSize ( - // Test that an overflow is detected - PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; - PrimaryHeader.SizeOfPartitionEntry = 5; -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - // Test the inverse - PrimaryHeader.NumberOfPartitionEntries = 5; - PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - // Test the worst case scenario - PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; - PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -@@ -196,7 +196,7 @@ TestSanitizePrimaryHeaderGptEventSize ( - NumberOfPartition = 13; - - // that the primary event size is correct -- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Calculate the existing logic event size -@@ -207,12 +207,12 @@ TestSanitizePrimaryHeaderGptEventSize ( - UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); - - // Tests that the primary event size may not overflow -- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); -+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - // Test that the size of partition entries may not overflow - PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -@@ -245,7 +245,7 @@ TestSanitizePeImageEventSize ( - FilePathSize = 255; - - // Test that a normal PE image passes validation -- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize); - UT_ASSERT_EQUAL (Status, EFI_SUCCESS); - - // Test that the event size is correct compared to the existing logic -@@ -258,7 +258,7 @@ TestSanitizePeImageEventSize ( - } - - // Test that the event size may not overflow -- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); -+ Status = Tpm2SanitizePeImageEventSize (MAX_UINT32, &EventSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); --- -2.33.0 - diff --git a/0019-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch b/0019-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch deleted file mode 100644 index 8a7798191faff0111dab9002eba760fe1df5eb5a..0000000000000000000000000000000000000000 --- a/0019-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 9c71ea26dff1adc7433fd15a27e46d53bc932711 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Wed, 17 Jan 2024 14:47:21 -0800 -Subject: [PATCH 08/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH - 4117/4118 symbol rename - -Updates the sanitation function names to be lib unique names - -Cc: Jiewen Yao -Cc: Rahul Kumar - -Signed-off-by: Doug Flick [MSFT] -Message-Id: <355aa846a99ca6ac0f7574cf5982661da0d9fea6.1705529990.git.doug.edk2@gmail.com> -Reviewed-by: Jiewen Yao - -reference: https://github.com/tianocore/edk2/pull/5273 -Signed-off-by: yexiao ---- - .../DxeTpmMeasureBootLib.c | 8 +++--- - .../DxeTpmMeasureBootLibSanitization.c | 10 +++---- - .../DxeTpmMeasureBootLibSanitization.h | 8 +++--- - .../DxeTpmMeasureBootLibSanitizationTest.c | 26 +++++++++---------- - 4 files changed, 26 insertions(+), 26 deletions(-) - -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -index 23329185..cf358e35 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c -@@ -174,7 +174,7 @@ TcgMeasureGptTable ( - BlockIo->Media->BlockSize, - (UINT8 *)PrimaryHeader - ); -- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { -+ if (EFI_ERROR (Status) || EFI_ERROR (TpmSanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { - DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); - FreePool (PrimaryHeader); - return EFI_DEVICE_ERROR; -@@ -183,7 +183,7 @@ TcgMeasureGptTable ( - // - // Read the partition entry. - // -- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); -+ Status = TpmSanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); - if (EFI_ERROR (Status)) { - FreePool (PrimaryHeader); - return EFI_DEVICE_ERROR; -@@ -224,7 +224,7 @@ TcgMeasureGptTable ( - // - // Prepare Data for Measurement - // -- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); -+ Status = TpmSanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); - TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize); - if (TcgEvent == NULL) { - FreePool (PrimaryHeader); -@@ -351,7 +351,7 @@ TcgMeasurePeImage ( - - // Determine destination PCR by BootPolicy - // -- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -index 33a230f8..c72a3491 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c -@@ -1,5 +1,5 @@ - /** @file -- The library instance provides security service of TPM2 measure boot and -+ The library instance provides security service of TPM measure boot and - Confidential Computing (CC) measure boot. - - Caution: This file requires additional review when modified. -@@ -63,7 +63,7 @@ - **/ - EFI_STATUS - EFIAPI --SanitizeEfiPartitionTableHeader ( -+TpmSanitizeEfiPartitionTableHeader ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo - ) -@@ -145,7 +145,7 @@ SanitizeEfiPartitionTableHeader ( - **/ - EFI_STATUS - EFIAPI --SanitizePrimaryHeaderAllocationSize ( -+TpmSanitizePrimaryHeaderAllocationSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - OUT UINT32 *AllocationSize - ) -@@ -194,7 +194,7 @@ SanitizePrimaryHeaderAllocationSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePrimaryHeaderGptEventSize ( -+TpmSanitizePrimaryHeaderGptEventSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN UINTN NumberOfPartition, - OUT UINT32 *EventSize -@@ -258,7 +258,7 @@ SanitizePrimaryHeaderGptEventSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePeImageEventSize ( -+TpmSanitizePeImageEventSize ( - IN UINT32 FilePathSize, - OUT UINT32 *EventSize - ) -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -index 181aba42..bbde1010 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h -@@ -53,7 +53,7 @@ - **/ - EFI_STATUS - EFIAPI --SanitizeEfiPartitionTableHeader ( -+TpmSanitizeEfiPartitionTableHeader ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo - ); -@@ -77,7 +77,7 @@ SanitizeEfiPartitionTableHeader ( - **/ - EFI_STATUS - EFIAPI --SanitizePrimaryHeaderAllocationSize ( -+TpmSanitizePrimaryHeaderAllocationSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - OUT UINT32 *AllocationSize - ); -@@ -105,7 +105,7 @@ SanitizePrimaryHeaderAllocationSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePrimaryHeaderGptEventSize ( -+TpmSanitizePrimaryHeaderGptEventSize ( - IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, - IN UINTN NumberOfPartition, - OUT UINT32 *EventSize -@@ -129,7 +129,7 @@ SanitizePrimaryHeaderGptEventSize ( - One of the passed parameters was invalid. - **/ - EFI_STATUS --SanitizePeImageEventSize ( -+TpmSanitizePeImageEventSize ( - IN UINT32 FilePathSize, - OUT UINT32 *EventSize - ); -diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -index 77a67826..e00dfaba 100644 ---- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c -@@ -83,27 +83,27 @@ TestSanitizeEfiPartitionTableHeader ( - PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); - - // Test that a normal PrimaryHeader passes validation -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR - // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" - PrimaryHeader.NumberOfPartitionEntries = 0; -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); - PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; - - // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR - // Should print "Invalid Partition Table Header Size!" - PrimaryHeader.Header.HeaderSize = 0; -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); - PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); - - // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR - // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" - PrimaryHeader.SizeOfPartitionEntry = 1; -- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); -+ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); - UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); - - DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -@@ -136,7 +136,7 @@ TestSanitizePrimaryHeaderAllocationSize ( - PrimaryHeader.NumberOfPartitionEntries = 5; - PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; - -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Test that the allocation size is correct compared to the existing logic -@@ -145,19 +145,19 @@ TestSanitizePrimaryHeaderAllocationSize ( - // Test that an overflow is detected - PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; - PrimaryHeader.SizeOfPartitionEntry = 5; -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - // Test the inverse - PrimaryHeader.NumberOfPartitionEntries = 5; - PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - // Test the worst case scenario - PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; - PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); -+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -@@ -195,7 +195,7 @@ TestSanitizePrimaryHeaderGptEventSize ( - NumberOfPartition = 13; - - // that the primary event size is correct -- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Calculate the existing logic event size -@@ -206,12 +206,12 @@ TestSanitizePrimaryHeaderGptEventSize ( - UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); - - // Tests that the primary event size may not overflow -- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); -+ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - // Test that the size of partition entries may not overflow - PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; -- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); -+ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); - UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); - - DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); -@@ -269,7 +269,7 @@ TestSanitizePeImageEventSize ( - FilePathSize = 255; - - // Test that a normal PE image passes validation -- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); -+ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize); - if (EFI_ERROR (Status)) { - UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status); - goto Exit; -@@ -285,7 +285,7 @@ TestSanitizePeImageEventSize ( - } - - // Test that the event size may not overflow -- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); -+ Status = TpmSanitizePeImageEventSize (MAX_UINT32, &EventSize); - if (Status != EFI_BAD_BUFFER_SIZE) { - UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status); - goto Exit; --- -2.33.0 - diff --git a/0020-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch b/0020-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch deleted file mode 100644 index 64dec4107b9b99a9733f6b356baa8e9823cac3a9..0000000000000000000000000000000000000000 --- a/0020-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 73ef289cdda1352b5fabf4ba281993e2ba91b511 Mon Sep 17 00:00:00 2001 -From: Gua Guo -Date: Thu, 11 Jan 2024 13:07:50 +0800 -Subject: [PATCH 09/10] EmbeddedPkg/Hob: Integer Overflow in CreateHob() - -REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4166 - -Fix integer overflow in various CreateHob instances. -Fixes: CVE-2022-36765 - -The CreateHob() function aligns the requested size to 8 -performing the following operation: -``` -HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); -``` - -No checks are performed to ensure this value doesn't -overflow, and could lead to CreateHob() returning a smaller -HOB than requested, which could lead to OOB HOB accesses. - -Reported-by: Marc Beatove -Cc: Leif Lindholm -Reviewed-by: Ard Biesheuvel -Cc: Abner Chang -Cc: John Mathew -Authored-by: Gerd Hoffmann -Signed-off-by: Gua Guo - -reference: https://github.com/tianocore/edk2/pull/5273 -Signed-off-by: yexiao ---- - EmbeddedPkg/Library/PrePiHobLib/Hob.c | 43 +++++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - -diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c -index 8eb175aa..d771497f 100644 ---- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c -+++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c -@@ -110,6 +110,13 @@ CreateHob ( - - HandOffHob = GetHobList (); - -+ // -+ // Check Length to avoid data overflow. -+ // -+ if (HobLength > MAX_UINT16 - 0x7) { -+ return NULL; -+ } -+ - HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); - - FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; -@@ -160,6 +167,9 @@ BuildResourceDescriptorHob ( - - Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); - ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->ResourceType = ResourceType; - Hob->ResourceAttribute = ResourceAttribute; -@@ -401,6 +411,10 @@ BuildModuleHob ( - ); - - Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); - Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; -@@ -449,6 +463,11 @@ BuildGuidHob ( - ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE))); - - Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return NULL; -+ } -+ - CopyGuid (&Hob->Name, Guid); - return Hob + 1; - } -@@ -512,6 +531,10 @@ BuildFvHob ( - EFI_HOB_FIRMWARE_VOLUME *Hob; - - Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->BaseAddress = BaseAddress; - Hob->Length = Length; -@@ -543,6 +566,10 @@ BuildFv2Hob ( - EFI_HOB_FIRMWARE_VOLUME2 *Hob; - - Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->BaseAddress = BaseAddress; - Hob->Length = Length; -@@ -584,6 +611,10 @@ BuildFv3Hob ( - EFI_HOB_FIRMWARE_VOLUME3 *Hob; - - Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->BaseAddress = BaseAddress; - Hob->Length = Length; -@@ -639,6 +670,10 @@ BuildCpuHob ( - EFI_HOB_CPU *Hob; - - Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->SizeOfMemorySpace = SizeOfMemorySpace; - Hob->SizeOfIoSpace = SizeOfIoSpace; -@@ -676,6 +711,10 @@ BuildStackHob ( - ); - - Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid); - Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; -@@ -756,6 +795,10 @@ BuildMemoryAllocationHob ( - ); - - Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); - Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; --- -2.33.0 - diff --git a/0021-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Pa.patch b/0021-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Pa.patch deleted file mode 100644 index d3ee1761b258783a2a8e55f24c36eec4fd5856e5..0000000000000000000000000000000000000000 --- a/0021-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Pa.patch +++ /dev/null @@ -1,1619 +0,0 @@ -From d8f3f9bf7bd42d84a0defc6885a2e7d3c45b53fb Mon Sep 17 00:00:00 2001 -From: "Doug Flick via groups.io" -Date: Fri, 26 Jan 2024 05:54:43 +0800 -Subject: [PATCH 01/19] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 - Patch - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535 - -Bug Details: -PixieFail Bug #2 -CVE-2023-45230 -CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H -CWE-119 Improper Restriction of Operations within the Bounds - of a Memory Buffer - -Changes Overview: -> -UINT8 * -> +EFI_STATUS -> Dhcp6AppendOption ( -> - IN OUT UINT8 *Buf, -> - IN UINT16 OptType, -> - IN UINT16 OptLen, -> - IN UINT8 *Data -> + IN OUT EFI_DHCP6_PACKET *Packet, -> + IN OUT UINT8 **PacketCursor, -> + IN UINT16 OptType, -> + IN UINT16 OptLen, -> + IN UINT8 *Data -> ); - -Dhcp6AppendOption() and variants can return errors now. All callsites -are adapted accordingly. - -It gets passed in EFI_DHCP6_PACKET as additional parameter ... - -> + // -> + // Verify the PacketCursor is within the packet -> + // -> + if ( (*PacketCursor < Packet->Dhcp6.Option) -> + || (*PacketCursor >= Packet->Dhcp6.Option + - (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -> + { -> + return EFI_INVALID_PARAMETER; -> + } - -... so it can look at Packet->Size when checking buffer space. -Also to allow Packet->Length updates. - -Lots of checks added. - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 43 +++ - NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 413 +++++++++++++++++++---------- - NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 377 ++++++++++++++++++++------ - NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h | 82 +++--- - 4 files changed, 672 insertions(+), 243 deletions(-) - -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h -index 0eb9c669..89c84a67 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h -@@ -45,6 +45,49 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; - #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S') - #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I') - -+// -+// For more information on DHCP options see RFC 8415, Section 21.1 -+// -+// The format of DHCP options is: -+// -+// 0 1 2 3 -+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | option-code | option-len | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | option-data | -+// | (option-len octets) | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// -+#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16)) -+#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16)) -+ -+// -+// Combined size of Code and Length -+// -+#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \ -+ DHCP6_SIZE_OF_OPT_LEN) -+ -+STATIC_ASSERT ( -+ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN == 4, -+ "Combined size of Code and Length must be 4 per RFC 8415" -+ ); -+ -+// -+// Offset to the length is just past the code -+// -+#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE) -+STATIC_ASSERT ( -+ DHCP6_OPT_LEN_OFFSET (0) == 2, -+ "Offset of length is + 2 past start of option" -+ ); -+ -+#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) -+STATIC_ASSERT ( -+ DHCP6_OPT_DATA_OFFSET (0) == 4, -+ "Offset to option data should be +4 from start of option" -+ ); -+ - #define DHCP6_PACKET_ALL 0 - #define DHCP6_PACKET_STATEFUL 1 - #define DHCP6_PACKET_STATELESS 2 -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -index dcd01e62..bde2362c 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -@@ -3,9 +3,9 @@ - - (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
-+ Copyright (c) Microsoft Corporation - - SPDX-License-Identifier: BSD-2-Clause-Patent -- - **/ - - #include "Dhcp6Impl.h" -@@ -930,7 +930,8 @@ Dhcp6SendSolicitMsg ( - // - Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); - if (Packet == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; - } - - Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; -@@ -944,54 +945,64 @@ Dhcp6SendSolicitMsg ( - Cursor = Packet->Dhcp6.Option; - - Length = HTONS (ClientId->Length); -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptClientId), - Length, - ClientId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendETOption ( -- Cursor, -+ Status = Dhcp6AppendETOption ( -+ Packet, -+ &Cursor, - Instance, - &Elapsed - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendIaOption ( -- Cursor, -+ Status = Dhcp6AppendIaOption ( -+ Packet, -+ &Cursor, - Instance->IaCb.Ia, - Instance->IaCb.T1, - Instance->IaCb.T2, - Packet->Dhcp6.Header.MessageType - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - - // - // Append user-defined when configurate Dhcp6 service. - // - for (Index = 0; Index < Instance->Config->OptionCount; Index++) { - UserOpt = Instance->Config->OptionList[Index]; -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - UserOpt->OpCode, - UserOpt->OpLen, - UserOpt->Data - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - } - -- // -- // Determine the size/length of packet. -- // -- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); - ASSERT (Packet->Size > Packet->Length + 8); - - // - // Callback to user with the packet to be sent and check the user's feedback. - // - Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // -@@ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg ( - Instance->StartTime = 0; - - Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // -@@ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg ( - Elapsed, - Instance->Config->SolicitRetransmission - ); -+ -+ON_ERROR: -+ -+ if (Packet) { -+ FreePool (Packet); -+ } -+ -+ return Status; - } - - /** -@@ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg ( - // - Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); - if (Packet == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; - } - - Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; -@@ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg ( - Cursor = Packet->Dhcp6.Option; - - Length = HTONS (ClientId->Length); -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptClientId), - Length, - ClientId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendETOption ( -- Cursor, -+ Status = Dhcp6AppendETOption ( -+ Packet, -+ &Cursor, - Instance, - &Elapsed - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptServerId), - ServerId->Length, - ServerId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendIaOption ( -- Cursor, -+ Status = Dhcp6AppendIaOption ( -+ Packet, -+ &Cursor, - Instance->IaCb.Ia, - Instance->IaCb.T1, - Instance->IaCb.T2, - Packet->Dhcp6.Header.MessageType - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - - // - // Append user-defined when configurate Dhcp6 service. - // - for (Index = 0; Index < Instance->Config->OptionCount; Index++) { - UserOpt = Instance->Config->OptionList[Index]; -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - UserOpt->OpCode, - UserOpt->OpLen, - UserOpt->Data - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - } - -- // -- // Determine the size/length of packet. -- // -- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); - ASSERT (Packet->Size > Packet->Length + 8); - - // -@@ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg ( - Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); - - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // -@@ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg ( - Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); - - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // - // Enqueue the sent packet for the retransmission in case reply timeout. - // - return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); -+ -+ON_ERROR: -+ -+ if (Packet) { -+ FreePool (Packet); -+ } -+ -+ return Status; - } - - /** -@@ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg ( - // - Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); - if (Packet == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; - } - - Packet->Size = DHCP6_BASE_PACKET_SIZE; -@@ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg ( - Cursor = Packet->Dhcp6.Option; - - Length = HTONS (ClientId->Length); -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptClientId), - Length, - ClientId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendETOption ( -- Cursor, -+ Status = Dhcp6AppendETOption ( -+ Packet, -+ &Cursor, - Instance, - &Elapsed - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptServerId), - ServerId->Length, - ServerId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } -+ -+ Status = Dhcp6AppendIaOption ( -+ Packet, -+ &Cursor, -+ DecIa, -+ 0, -+ 0, -+ Packet->Dhcp6.Header.MessageType -+ ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType); -- -- // -- // Determine the size/length of packet. -- // -- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); - ASSERT (Packet->Size > Packet->Length + 8); - - // - // Callback to user with the packet to be sent and check the user's feedback. - // - Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // -@@ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg ( - Instance->StartTime = 0; - - Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // - // Enqueue the sent packet for the retransmission in case reply timeout. - // - return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); -+ -+ON_ERROR: -+ -+ if (Packet) { -+ FreePool (Packet); -+ } -+ -+ return Status; - } - - /** -@@ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg ( - // - Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); - if (Packet == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; - } - - Packet->Size = DHCP6_BASE_PACKET_SIZE; -@@ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg ( - Cursor = Packet->Dhcp6.Option; - - Length = HTONS (ClientId->Length); -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptClientId), - Length, - ClientId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - - // - // ServerId is extracted from packet, it's network order. - // -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptServerId), - ServerId->Length, - ServerId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendETOption ( -- Cursor, -+ Status = Dhcp6AppendETOption ( -+ Packet, -+ &Cursor, - Instance, - &Elapsed - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } -+ -+ Status = Dhcp6AppendIaOption ( -+ Packet, -+ &Cursor, -+ RelIa, -+ 0, -+ 0, -+ Packet->Dhcp6.Header.MessageType -+ ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType); -- -- // -- // Determine the size/length of packet -- // -- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); - ASSERT (Packet->Size > Packet->Length + 8); - - // - // Callback to user with the packet to be sent and check the user's feedback. - // - Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // -@@ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg ( - Instance->IaCb.Ia->State = Dhcp6Releasing; - - Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // - // Enqueue the sent packet for the retransmission in case reply timeout. - // - return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); -+ -+ON_ERROR: -+ -+ if (Packet) { -+ FreePool (Packet); -+ } -+ -+ return Status; - } - - /** -@@ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg ( - // - Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); - if (Packet == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; - } - - Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; -@@ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg ( - Cursor = Packet->Dhcp6.Option; - - Length = HTONS (ClientId->Length); -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptClientId), - Length, - ClientId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendETOption ( -- Cursor, -+ Status = Dhcp6AppendETOption ( -+ Packet, -+ &Cursor, - Instance, - &Elapsed - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendIaOption ( -- Cursor, -+ Status = Dhcp6AppendIaOption ( -+ Packet, -+ &Cursor, - Instance->IaCb.Ia, - Instance->IaCb.T1, - Instance->IaCb.T2, - Packet->Dhcp6.Header.MessageType - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - - if (!RebindRequest) { - // -@@ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg ( - Dhcp6OptServerId - ); - if (Option == NULL) { -- FreePool (Packet); -- return EFI_DEVICE_ERROR; -+ Status = EFI_DEVICE_ERROR; -+ goto ON_ERROR; - } - - ServerId = (EFI_DHCP6_DUID *)(Option + 2); - -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptServerId), - ServerId->Length, - ServerId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - } - - // -@@ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg ( - // - for (Index = 0; Index < Instance->Config->OptionCount; Index++) { - UserOpt = Instance->Config->OptionList[Index]; -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - UserOpt->OpCode, - UserOpt->OpLen, - UserOpt->Data - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - } - -- // -- // Determine the size/length of packet. -- // -- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); - ASSERT (Packet->Size > Packet->Length + 8); - - // -@@ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg ( - Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing; - - Status = Dhcp6CallbackUser (Instance, Event, &Packet); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // -@@ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg ( - Instance->StartTime = 0; - - Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // - // Enqueue the sent packet for the retransmission in case reply timeout. - // - return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); -+ -+ON_ERROR: -+ -+ if (Packet) { -+ FreePool (Packet); -+ } -+ -+ return Status; - } - - /** -@@ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg ( - // - Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); - if (Packet == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; - } - - Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; -@@ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg ( - - if (SendClientId) { - Length = HTONS (ClientId->Length); -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptClientId), - Length, - ClientId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - } - -- Cursor = Dhcp6AppendETOption ( -- Cursor, -+ Status = Dhcp6AppendETOption ( -+ Packet, -+ &Cursor, - Instance, - &Elapsed - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - OptionRequest->OpCode, - OptionRequest->OpLen, - OptionRequest->Data - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - - // - // Append user-defined when configurate Dhcp6 service. - // - for (Index = 0; Index < OptionCount; Index++) { - UserOpt = OptionList[Index]; -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - UserOpt->OpCode, - UserOpt->OpLen, - UserOpt->Data - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - } - -- // -- // Determine the size/length of packet. -- // -- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); - ASSERT (Packet->Size > Packet->Length + 8); - - // -@@ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg ( - // Send info-request packet with no state. - // - Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // - // Enqueue the sent packet for the retransmission in case reply timeout. - // - return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission); -+ -+ON_ERROR: -+ -+ if (Packet) { -+ FreePool (Packet); -+ } -+ -+ return Status; - } - - /** -@@ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg ( - // - Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); - if (Packet == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; - } - - Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; -@@ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg ( - Cursor = Packet->Dhcp6.Option; - - Length = HTONS (ClientId->Length); -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - HTONS (Dhcp6OptClientId), - Length, - ClientId->Duid - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendETOption ( -- Cursor, -+ Status = Dhcp6AppendETOption ( -+ Packet, -+ &Cursor, - Instance, - &Elapsed - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - -- Cursor = Dhcp6AppendIaOption ( -- Cursor, -+ Status = Dhcp6AppendIaOption ( -+ Packet, -+ &Cursor, - Instance->IaCb.Ia, - Instance->IaCb.T1, - Instance->IaCb.T2, - Packet->Dhcp6.Header.MessageType - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - - // - // Append user-defined when configurate Dhcp6 service. - // - for (Index = 0; Index < Instance->Config->OptionCount; Index++) { - UserOpt = Instance->Config->OptionList[Index]; -- Cursor = Dhcp6AppendOption ( -- Cursor, -+ Status = Dhcp6AppendOption ( -+ Packet, -+ &Cursor, - UserOpt->OpCode, - UserOpt->OpLen, - UserOpt->Data - ); -+ if (EFI_ERROR (Status)) { -+ goto ON_ERROR; -+ } - } - -- // -- // Determine the size/length of packet. -- // -- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); - ASSERT (Packet->Size > Packet->Length + 8); - - // - // Callback to user with the packet to be sent and check the user's feedback. - // - Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // -@@ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg ( - Instance->StartTime = 0; - - Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); -- - if (EFI_ERROR (Status)) { -- FreePool (Packet); -- return Status; -+ goto ON_ERROR; - } - - // - // Enqueue the sent packet for the retransmission in case reply timeout. - // - return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); -+ -+ON_ERROR: -+ -+ if (Packet) { -+ FreePool (Packet); -+ } -+ -+ return Status; - } - - /** -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -index e6368b5b..e9c45072 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -@@ -577,24 +577,33 @@ Dhcp6OnTransmitted ( - } - - /** -- Append the option to Buf, and move Buf to the end. -+ Append the option to Buf, update the length of packet, and move Buf to the end. - -- @param[in, out] Buf The pointer to the buffer. -- @param[in] OptType The option type. -- @param[in] OptLen The length of option contents. -- @param[in] Data The pointer to the option content. -+ @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ will be updated. -+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor -+ will be moved to the end of the option. -+ @param[in] OptType The option type. -+ @param[in] OptLen The length of option contents. -+ @param[in] Data The pointer to the option content. - -- @return Buf The position to append the next option. -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - - **/ --UINT8 * -+EFI_STATUS - Dhcp6AppendOption ( -- IN OUT UINT8 *Buf, -- IN UINT16 OptType, -- IN UINT16 OptLen, -- IN UINT8 *Data -+ IN OUT EFI_DHCP6_PACKET *Packet, -+ IN OUT UINT8 **PacketCursor, -+ IN UINT16 OptType, -+ IN UINT16 OptLen, -+ IN UINT8 *Data - ) - { -+ UINT32 Length; -+ UINT32 BytesNeeded; -+ - // - // The format of Dhcp6 option: - // -@@ -607,35 +616,95 @@ Dhcp6AppendOption ( - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // - -- ASSERT (OptLen != 0); -- -- WriteUnaligned16 ((UINT16 *)Buf, OptType); -- Buf += 2; -- WriteUnaligned16 ((UINT16 *)Buf, OptLen); -- Buf += 2; -- CopyMem (Buf, Data, NTOHS (OptLen)); -- Buf += NTOHS (OptLen); -- -- return Buf; -+ // -+ // Verify the arguments are valid -+ // -+ if (Packet == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (Data == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (OptLen == 0) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Verify the PacketCursor is within the packet -+ // -+ if ( (*PacketCursor < Packet->Dhcp6.Option) -+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -+ { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Calculate the bytes needed for the option -+ // -+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen); -+ -+ // -+ // Space remaining in the packet -+ // -+ Length = Packet->Size - Packet->Length; -+ if (Length < BytesNeeded) { -+ return EFI_BUFFER_TOO_SMALL; -+ } -+ -+ // -+ // Verify the PacketCursor is within the packet -+ // -+ if ( (*PacketCursor < Packet->Dhcp6.Option) -+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -+ { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); -+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); -+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; -+ CopyMem (*PacketCursor, Data, NTOHS (OptLen)); -+ *PacketCursor += NTOHS (OptLen); -+ -+ // Update the packet length by the length of the option + 4 bytes -+ Packet->Length += BytesNeeded; -+ -+ return EFI_SUCCESS; - } - - /** - Append the appointed IA Address option to Buf, and move Buf to the end. - -- @param[in, out] Buf The pointer to the position to append. -+ @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ will be updated. -+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor -+ will be moved to the end of the option. - @param[in] IaAddr The pointer to the IA Address. - @param[in] MessageType Message type of DHCP6 package. - -- @return Buf The position to append the next option. -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - - **/ --UINT8 * -+EFI_STATUS - Dhcp6AppendIaAddrOption ( -- IN OUT UINT8 *Buf, -+ IN OUT EFI_DHCP6_PACKET *Packet, -+ IN OUT UINT8 **PacketCursor, - IN EFI_DHCP6_IA_ADDRESS *IaAddr, - IN UINT32 MessageType - ) - { -+ UINT32 BytesNeeded; -+ UINT32 Length; -+ - // The format of the IA Address option is: - // - // 0 1 2 3 -@@ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption ( - // . . - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -+ // -+ // Verify the arguments are valid -+ // -+ if (Packet == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (IaAddr == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Verify the PacketCursor is within the packet -+ // -+ if ( (*PacketCursor < Packet->Dhcp6.Option) -+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -+ { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; -+ BytesNeeded += sizeof (EFI_IPv6_ADDRESS); -+ // -+ // Even if the preferred-lifetime is 0, it still needs to store it. -+ // -+ BytesNeeded += sizeof (IaAddr->PreferredLifetime); -+ // -+ // Even if the valid-lifetime is 0, it still needs to store it. -+ // -+ BytesNeeded += sizeof (IaAddr->ValidLifetime); -+ -+ // -+ // Space remaining in the packet -+ // -+ Length = Packet->Size - Packet->Length; -+ if (Length < BytesNeeded) { -+ return EFI_BUFFER_TOO_SMALL; -+ } -+ - // - // Fill the value of Ia Address option type - // -- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr)); -- Buf += 2; -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr)); -+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; - -- WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); -- Buf += 2; -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); -+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; - -- CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); -- Buf += sizeof (EFI_IPv6_ADDRESS); -+ CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); -+ *PacketCursor += sizeof (EFI_IPv6_ADDRESS); - - // - // Fill the value of preferred-lifetime and valid-lifetime. -@@ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption ( - // should set to 0 when initiate a Confirm message. - // - if (MessageType != Dhcp6MsgConfirm) { -- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime)); -+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime)); - } - -- Buf += 4; -+ *PacketCursor += sizeof (IaAddr->PreferredLifetime); - - if (MessageType != Dhcp6MsgConfirm) { -- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime)); -+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime)); - } - -- Buf += 4; -+ *PacketCursor += sizeof (IaAddr->ValidLifetime); -+ -+ // -+ // Update the packet length -+ // -+ Packet->Length += BytesNeeded; - -- return Buf; -+ return EFI_SUCCESS; - } - - /** - Append the appointed Ia option to Buf, and move Buf to the end. - -- @param[in, out] Buf The pointer to the position to append. -+ @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ will be updated. -+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor -+ will be moved to the end of the option. - @param[in] Ia The pointer to the Ia. - @param[in] T1 The time of T1. - @param[in] T2 The time of T2. - @param[in] MessageType Message type of DHCP6 package. - -- @return Buf The position to append the next Ia option. -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - - **/ --UINT8 * -+EFI_STATUS - Dhcp6AppendIaOption ( -- IN OUT UINT8 *Buf, -- IN EFI_DHCP6_IA *Ia, -- IN UINT32 T1, -- IN UINT32 T2, -- IN UINT32 MessageType -+ IN OUT EFI_DHCP6_PACKET *Packet, -+ IN OUT UINT8 **PacketCursor, -+ IN EFI_DHCP6_IA *Ia, -+ IN UINT32 T1, -+ IN UINT32 T2, -+ IN UINT32 MessageType - ) - { -- UINT8 *AddrOpt; -- UINT16 *Len; -- UINTN Index; -+ UINT8 *AddrOpt; -+ UINT16 *Len; -+ UINTN Index; -+ UINT32 BytesNeeded; -+ UINT32 Length; -+ EFI_STATUS Status; - - // - // The format of IA_NA and IA_TA option: -@@ -733,32 +859,74 @@ Dhcp6AppendIaOption ( - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // - -+ // -+ // Verify the arguments are valid -+ // -+ if (Packet == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (Ia == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Verify the PacketCursor is within the packet -+ // -+ if ( (*PacketCursor < Packet->Dhcp6.Option) -+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -+ { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; -+ BytesNeeded += sizeof (Ia->Descriptor.IaId); -+ // -+ // + N for the IA_NA-options/IA_TA-options -+ // Dhcp6AppendIaAddrOption will need to check the length for each address -+ // -+ if (Ia->Descriptor.Type == Dhcp6OptIana) { -+ BytesNeeded += sizeof (T1) + sizeof (T2); -+ } -+ -+ // -+ // Space remaining in the packet -+ // -+ Length = (UINT16)(Packet->Size - Packet->Length); -+ if (Length < BytesNeeded) { -+ return EFI_BUFFER_TOO_SMALL; -+ } -+ - // - // Fill the value of Ia option type - // -- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type)); -- Buf += 2; -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type)); -+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; - - // - // Fill the len of Ia option later, keep the pointer first - // -- Len = (UINT16 *)Buf; -- Buf += 2; -+ Len = (UINT16 *)*PacketCursor; -+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; - - // - // Fill the value of iaid - // -- WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId)); -- Buf += 4; -+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId)); -+ *PacketCursor += sizeof (Ia->Descriptor.IaId); - - // - // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified. - // - if (Ia->Descriptor.Type == Dhcp6OptIana) { -- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff)); -- Buf += 4; -- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff)); -- Buf += 4; -+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff)); -+ *PacketCursor += sizeof (T1); -+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff)); -+ *PacketCursor += sizeof (T2); - } - - // -@@ -766,35 +934,51 @@ Dhcp6AppendIaOption ( - // - for (Index = 0; Index < Ia->IaAddressCount; Index++) { - AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS); -- Buf = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); -+ Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); -+ if (EFI_ERROR (Status)) { -+ return Status; -+ } - } - - // - // Fill the value of Ia option length - // -- *Len = HTONS ((UINT16)(Buf - (UINT8 *)Len - 2)); -+ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); - -- return Buf; -+ // -+ // Update the packet length -+ // -+ Packet->Length += BytesNeeded; -+ -+ return EFI_SUCCESS; - } - - /** - Append the appointed Elapsed time option to Buf, and move Buf to the end. - -- @param[in, out] Buf The pointer to the position to append. -+ @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor -+ will be moved to the end of the option. - @param[in] Instance The pointer to the Dhcp6 instance. - @param[out] Elapsed The pointer to the elapsed time value in -- the generated packet. -+ the generated packet. - -- @return Buf The position to append the next Ia option. -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - - **/ --UINT8 * -+EFI_STATUS - Dhcp6AppendETOption ( -- IN OUT UINT8 *Buf, -- IN DHCP6_INSTANCE *Instance, -- OUT UINT16 **Elapsed -+ IN OUT EFI_DHCP6_PACKET *Packet, -+ IN OUT UINT8 **PacketCursor, -+ IN DHCP6_INSTANCE *Instance, -+ OUT UINT16 **Elapsed - ) - { -+ UINT32 BytesNeeded; -+ UINT32 Length; -+ - // - // The format of elapsed time option: - // -@@ -806,27 +990,70 @@ Dhcp6AppendETOption ( - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // - -+ // -+ // Verify the arguments are valid -+ // -+ if (Packet == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if (Instance == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ if ((Elapsed == NULL)) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Verify the PacketCursor is within the packet -+ // -+ if ( (*PacketCursor < Packet->Dhcp6.Option) -+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -+ { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; -+ // -+ // + 2 for elapsed-time -+ // -+ BytesNeeded += sizeof (UINT16); -+ // -+ // Space remaining in the packet -+ // -+ Length = Packet->Size - Packet->Length; -+ if (Length < BytesNeeded) { -+ return EFI_BUFFER_TOO_SMALL; -+ } -+ - // - // Fill the value of elapsed-time option type. - // -- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime)); -- Buf += 2; -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime)); -+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; - - // - // Fill the len of elapsed-time option, which is fixed. - // -- WriteUnaligned16 ((UINT16 *)Buf, HTONS (2)); -- Buf += 2; -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2)); -+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; - - // - // Fill in elapsed time value with 0 value for now. The actual value is - // filled in later just before the packet is transmitted. - // -- WriteUnaligned16 ((UINT16 *)Buf, HTONS (0)); -- *Elapsed = (UINT16 *)Buf; -- Buf += 2; -+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0)); -+ *Elapsed = (UINT16 *)*PacketCursor; -+ *PacketCursor += sizeof (UINT16); - -- return Buf; -+ Packet->Length += BytesNeeded; -+ -+ return EFI_SUCCESS; - } - - /** -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h -index 046454ff..991e28c4 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h -@@ -160,69 +160,85 @@ Dhcp6OnTransmitted ( - ); - - /** -- Append the appointed option to the buf, and move the buf to the end. -- -- @param[in, out] Buf The pointer to buffer. -- @param[in] OptType The option type. -- @param[in] OptLen The length of option content.s -- @param[in] Data The pointer to the option content. -- -- @return Buf The position to append the next option. -- -+ Append the option to Buf, update the length of packet, and move Buf to the end. -+ -+ @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ will be updated. -+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor -+ will be moved to the end of the option. -+ @param[in] OptType The option type. -+ @param[in] OptLen The length of option contents. -+ @param[in] Data The pointer to the option content. -+ -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - **/ --UINT8 * -+EFI_STATUS - Dhcp6AppendOption ( -- IN OUT UINT8 *Buf, -- IN UINT16 OptType, -- IN UINT16 OptLen, -- IN UINT8 *Data -+ IN OUT EFI_DHCP6_PACKET *Packet, -+ IN OUT UINT8 **PacketCursor, -+ IN UINT16 OptType, -+ IN UINT16 OptLen, -+ IN UINT8 *Data - ); - - /** -- Append the Ia option to Buf, and move Buf to the end. -- -- @param[in, out] Buf The pointer to the position to append. -+ Append the appointed Ia option to Buf, update the Ia option length, and move Buf -+ to the end of the option. -+ @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ will be updated. -+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor -+ will be moved to the end of the option. - @param[in] Ia The pointer to the Ia. - @param[in] T1 The time of T1. - @param[in] T2 The time of T2. - @param[in] MessageType Message type of DHCP6 package. - -- @return Buf The position to append the next Ia option. -- -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - **/ --UINT8 * -+EFI_STATUS - Dhcp6AppendIaOption ( -- IN OUT UINT8 *Buf, -- IN EFI_DHCP6_IA *Ia, -- IN UINT32 T1, -- IN UINT32 T2, -- IN UINT32 MessageType -+ IN OUT EFI_DHCP6_PACKET *Packet, -+ IN OUT UINT8 **PacketCursor, -+ IN EFI_DHCP6_IA *Ia, -+ IN UINT32 T1, -+ IN UINT32 T2, -+ IN UINT32 MessageType - ); - - /** - Append the appointed Elapsed time option to Buf, and move Buf to the end. - -- @param[in, out] Buf The pointer to the position to append. -+ @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor -+ will be moved to the end of the option. - @param[in] Instance The pointer to the Dhcp6 instance. - @param[out] Elapsed The pointer to the elapsed time value in - the generated packet. - -- @return Buf The position to append the next Ia option. -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - - **/ --UINT8 * -+EFI_STATUS - Dhcp6AppendETOption ( -- IN OUT UINT8 *Buf, -- IN DHCP6_INSTANCE *Instance, -- OUT UINT16 **Elapsed -+ IN OUT EFI_DHCP6_PACKET *Packet, -+ IN OUT UINT8 **PacketCursor, -+ IN DHCP6_INSTANCE *Instance, -+ OUT UINT16 **Elapsed - ); - - /** - Set the elapsed time based on the given instance and the pointer to the - elapsed time option. - -- @param[in] Elapsed The pointer to the position to append. -- @param[in] Instance The pointer to the Dhcp6 instance. -+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid -+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. -+ @retval EFI_SUCCESS The option is appended successfully. - **/ - VOID - SetElapsedTime ( --- -2.33.0 - diff --git a/0021-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch b/0021-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch deleted file mode 100644 index 0ce04ca4d69f2b899e4eeb957d13d3235f1ca265..0000000000000000000000000000000000000000 --- a/0021-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch +++ /dev/null @@ -1,132 +0,0 @@ -From d1b5a360b8b4d8833c0f0e8de309a756b0cec347 Mon Sep 17 00:00:00 2001 -From: Gua Guo -Date: Thu, 11 Jan 2024 13:03:26 +0800 -Subject: [PATCH 10/10] StandaloneMmPkg/Hob: Integer Overflow in CreateHob() - -REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4166 - -Fix integer overflow in various CreateHob instances. -Fixes: CVE-2022-36765 - -The CreateHob() function aligns the requested size to 8 -performing the following operation: -``` -HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); -``` - -No checks are performed to ensure this value doesn't -overflow, and could lead to CreateHob() returning a smaller -HOB than requested, which could lead to OOB HOB accesses. - -Reported-by: Marc Beatove -Reviewed-by: Ard Biesheuvel -Cc: Sami Mujawar -Reviewed-by: Ray Ni -Cc: John Mathew -Authored-by: Gerd Hoffmann -Signed-off-by: Gua Guo - -reference: https://github.com/tianocore/edk2/pull/5273 -Signed-off-by: yexiao ---- - .../Arm/StandaloneMmCoreHobLib.c | 35 +++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c -index 1550e1ba..78677936 100644 ---- a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c -+++ b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c -@@ -34,6 +34,13 @@ CreateHob ( - - HandOffHob = GetHobList (); - -+ // -+ // Check Length to avoid data overflow. -+ // -+ if (HobLength > MAX_UINT16 - 0x7) { -+ return NULL; -+ } -+ - HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); - - FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; -@@ -89,6 +96,10 @@ BuildModuleHob ( - ); - - Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); - Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; -@@ -129,6 +140,9 @@ BuildResourceDescriptorHob ( - - Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); - ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->ResourceType = ResourceType; - Hob->ResourceAttribute = ResourceAttribute; -@@ -167,6 +181,11 @@ BuildGuidHob ( - ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE))); - - Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return NULL; -+ } -+ - CopyGuid (&Hob->Name, Guid); - return Hob + 1; - } -@@ -226,6 +245,10 @@ BuildFvHob ( - EFI_HOB_FIRMWARE_VOLUME *Hob; - - Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->BaseAddress = BaseAddress; - Hob->Length = Length; -@@ -255,6 +278,10 @@ BuildFv2Hob ( - EFI_HOB_FIRMWARE_VOLUME2 *Hob; - - Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->BaseAddress = BaseAddress; - Hob->Length = Length; -@@ -282,6 +309,10 @@ BuildCpuHob ( - EFI_HOB_CPU *Hob; - - Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - Hob->SizeOfMemorySpace = SizeOfMemorySpace; - Hob->SizeOfIoSpace = SizeOfIoSpace; -@@ -319,6 +350,10 @@ BuildMemoryAllocationHob ( - ); - - Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION)); -+ ASSERT (Hob != NULL); -+ if (Hob == NULL) { -+ return; -+ } - - ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); - Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; --- -2.33.0 - diff --git a/0022-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch b/0022-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch deleted file mode 100644 index 8788519296e5cb03292c900a5ddef9f7a32e5dcd..0000000000000000000000000000000000000000 --- a/0022-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 623554389e1733dac86045d7e0b9503c3f7224c1 Mon Sep 17 00:00:00 2001 -From: "Doug Flick via groups.io" -Date: Fri, 26 Jan 2024 05:54:44 +0800 -Subject: [PATCH 02/19] NetworkPkg: : Add Unit tests to CI and create Host Test - DSC - -Adds Host Based testing to the NetworkPkg - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/NetworkPkg.ci.yaml | 7 +- - NetworkPkg/Test/NetworkPkgHostTest.dsc | 98 ++++++++++++++++++++++++++ - 2 files changed, 104 insertions(+), 1 deletion(-) - create mode 100644 NetworkPkg/Test/NetworkPkgHostTest.dsc - -diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml -index 07dc7abd..3ecc7dca 100644 ---- a/NetworkPkg/NetworkPkg.ci.yaml -+++ b/NetworkPkg/NetworkPkg.ci.yaml -@@ -24,6 +24,9 @@ - "CompilerPlugin": { - "DscPath": "NetworkPkg.dsc" - }, -+ "HostUnitTestCompilerPlugin": { -+ "DscPath": "Test/NetworkPkgHostTest.dsc" -+ }, - "CharEncodingCheck": { - "IgnoreFiles": [] - }, -@@ -35,7 +38,9 @@ - "CryptoPkg/CryptoPkg.dec" - ], - # For host based unit tests -- "AcceptableDependencies-HOST_APPLICATION":[], -+ "AcceptableDependencies-HOST_APPLICATION":[ -+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec -+ ], - # For UEFI shell based apps - "AcceptableDependencies-UEFI_APPLICATION":[ - "ShellPkg/ShellPkg.dec" -diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc -new file mode 100644 -index 00000000..b74b2048 ---- /dev/null -+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc -@@ -0,0 +1,98 @@ -+## @file -+# NetworkPkgHostTest DSC file used to build host-based unit tests. -+# -+# Copyright (c) Microsoft Corporation.
-+# SPDX-License-Identifier: BSD-2-Clause-Patent -+# -+## -+[Defines] -+ PLATFORM_NAME = NetworkPkgHostTest -+ PLATFORM_GUID = 3b68324e-fc07-4d49-9520-9347ede65879 -+ PLATFORM_VERSION = 0.1 -+ DSC_SPECIFICATION = 0x00010005 -+ OUTPUT_DIRECTORY = Build/NetworkPkg/HostTest -+ SUPPORTED_ARCHITECTURES = IA32|X64|AARCH64 -+ BUILD_TARGETS = NOOPT -+ SKUID_IDENTIFIER = DEFAULT -+ -+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc -+[Packages] -+ MdePkg/MdePkg.dec -+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec -+ -+[Components] -+ # -+ # Build HOST_APPLICATION that tests NetworkPkg -+ # -+ -+# Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. -+[LibraryClasses] -+ NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf -+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf -+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf -+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf -+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf -+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf -+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf -+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf -+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf -+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf -+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf -+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf -+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf -+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf -+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf -+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf -+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf -+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf -+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf -+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf -+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf -+ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf -+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf -+ VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf -+!ifdef CONTINUOUS_INTEGRATION -+ BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf -+ TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf -+!else -+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf -+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf -+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf -+!endif -+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf -+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf -+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf -+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf -+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf -+ -+!if $(TOOL_CHAIN_TAG) == VS2019 or $(TOOL_CHAIN_TAG) == VS2022 -+[LibraryClasses.X64] -+ # Provide StackCookie support lib so that we can link to /GS exports for VS builds -+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf -+!endif -+ -+[LibraryClasses.common.UEFI_DRIVER] -+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf -+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf -+ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf -+[LibraryClasses.common.UEFI_APPLICATION] -+ DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf -+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf -+[LibraryClasses.ARM, LibraryClasses.AARCH64] -+ # -+ # It is not possible to prevent ARM compiler calls to generic intrinsic functions. -+ # This library provides the instrinsic functions generated by a given compiler. -+ # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. -+ # -+!if $(TOOL_CHAIN_TAG) != VS2017 and $(TOOL_CHAIN_TAG) != VS2015 and $(TOOL_CHAIN_TAG) != VS2019 -+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf -+!endif -+ NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf -+[LibraryClasses.ARM] -+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf -+[LibraryClasses.RISCV64] -+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf -+ -+[PcdsFixedAtBuild] -+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2 -+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|0x4 --- -2.33.0 - diff --git a/0023-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch b/0023-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch deleted file mode 100644 index 90a4da3662d4b8337b7b44b24482cd0c3e0396b5..0000000000000000000000000000000000000000 --- a/0023-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch +++ /dev/null @@ -1,614 +0,0 @@ -From 03bc678afd4810c9318f0a165a5c5659bf3af718 Mon Sep 17 00:00:00 2001 -From: "Doug Flick via groups.io" -Date: Fri, 26 Jan 2024 05:54:45 +0800 -Subject: [PATCH 03/19] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 - Unit Tests - -REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4535 - -Confirms that reported issue... - -"Buffer overflow in the DHCPv6 client via a long Server ID option" - -..has been corrected by the provided patch. - -Tests the following functions to ensure they appropriately handle -untrusted data (either too long or too small) to prevent a buffer -overflow: - -Dhcp6AppendOption -Dhcp6AppendETOption -Dhcp6AppendIaOption - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - .../GoogleTest/Dhcp6DxeGoogleTest.cpp | 20 + - .../GoogleTest/Dhcp6DxeGoogleTest.inf | 43 ++ - .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 478 ++++++++++++++++++ - NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + - 4 files changed, 542 insertions(+) - create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp - create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf - create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp - -diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp -new file mode 100644 -index 00000000..311b3992 ---- /dev/null -+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp -@@ -0,0 +1,20 @@ -+/** @file -+ Acts as the main entry point for the tests for the Dhcp6Dxe module. -+ -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+ -+//////////////////////////////////////////////////////////////////////////////// -+// Run the tests -+//////////////////////////////////////////////////////////////////////////////// -+int -+main ( -+ int argc, -+ char *argv[] -+ ) -+{ -+ testing::InitGoogleTest (&argc, argv); -+ return RUN_ALL_TESTS (); -+} -diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf -new file mode 100644 -index 00000000..253c61e8 ---- /dev/null -+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf -@@ -0,0 +1,43 @@ -+## @file -+# Unit test suite for the Dhcp6Dxe using Google Test -+# -+# Copyright (c) Microsoft Corporation.
-+# SPDX-License-Identifier: BSD-2-Clause-Patent -+## -+[Defines] -+ INF_VERSION = 0x00010017 -+ BASE_NAME = Dhcp6DxeGoogleTest -+ FILE_GUID = 1D2A4C65-38C8-4C2F-BB60-B5FA49625AA9 -+ VERSION_STRING = 1.0 -+ MODULE_TYPE = HOST_APPLICATION -+# -+# The following information is for reference only and not required by the build tools. -+# -+# VALID_ARCHITECTURES = IA32 X64 AARCH64 -+# -+[Sources] -+ Dhcp6DxeGoogleTest.cpp -+ Dhcp6IoGoogleTest.cpp -+ ../Dhcp6Io.c -+ ../Dhcp6Utility.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ MdeModulePkg/MdeModulePkg.dec -+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec -+ NetworkPkg/NetworkPkg.dec -+ -+[LibraryClasses] -+ GoogleTestLib -+ DebugLib -+ NetLib -+ PcdLib -+ -+[Protocols] -+ gEfiDhcp6ServiceBindingProtocolGuid -+ -+[Pcd] -+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType -+ -+[Guids] -+ gZeroGuid -diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp -new file mode 100644 -index 00000000..a2b8a9f8 ---- /dev/null -+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp -@@ -0,0 +1,478 @@ -+/** @file -+ Tests for Dhcp6Io.c. -+ -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+ -+extern "C" { -+ #include -+ #include -+ #include -+ #include -+ #include "../Dhcp6Impl.h" -+ #include "../Dhcp6Utility.h" -+} -+ -+//////////////////////////////////////////////////////////////////////// -+// Defines -+//////////////////////////////////////////////////////////////////////// -+ -+#define DHCP6_PACKET_MAX_LEN 1500 -+ -+//////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////// -+// Symbol Definitions -+// These functions are not directly under test - but required to compile -+//////////////////////////////////////////////////////////////////////// -+ -+// This definition is used by this test but is also required to compile -+// by Dhcp6Io.c -+EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = { -+ { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 } -+}; -+ -+EFI_STATUS -+EFIAPI -+UdpIoSendDatagram ( -+ IN UDP_IO *UdpIo, -+ IN NET_BUF *Packet, -+ IN UDP_END_POINT *EndPoint OPTIONAL, -+ IN EFI_IP_ADDRESS *Gateway OPTIONAL, -+ IN UDP_IO_CALLBACK CallBack, -+ IN VOID *Context -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ -+EFI_STATUS -+EFIAPI -+UdpIoRecvDatagram ( -+ IN UDP_IO *UdpIo, -+ IN UDP_IO_CALLBACK CallBack, -+ IN VOID *Context, -+ IN UINT32 HeadLen -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ -+//////////////////////////////////////////////////////////////////////// -+// Dhcp6AppendOptionTest Tests -+//////////////////////////////////////////////////////////////////////// -+ -+class Dhcp6AppendOptionTest : public ::testing::Test { -+public: -+ UINT8 *Buffer = NULL; -+ EFI_DHCP6_PACKET *Packet; -+ -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ // Initialize any resources or variables -+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); -+ ASSERT_NE (Buffer, (UINT8 *)NULL); -+ -+ Packet = (EFI_DHCP6_PACKET *)Buffer; -+ Packet->Size = DHCP6_PACKET_MAX_LEN; -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ // Clean up any resources or variables -+ if (Buffer != NULL) { -+ FreePool (Buffer); -+ } -+ } -+}; -+ -+// Test Description: -+// Attempt to append an option to a packet that is too small by a duid that is too large -+TEST_F (Dhcp6AppendOptionTest, InvalidDataExpectBufferTooSmall) { -+ UINT8 *Cursor; -+ EFI_DHCP6_DUID *UntrustedDuid; -+ EFI_STATUS Status; -+ -+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID)); -+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL); -+ -+ UntrustedDuid->Length = NTOHS (0xFFFF); -+ -+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option; -+ -+ Status = Dhcp6AppendOption ( -+ Dhcp6AppendOptionTest::Packet, -+ &Cursor, -+ HTONS (Dhcp6OptServerId), -+ UntrustedDuid->Length, -+ UntrustedDuid->Duid -+ ); -+ -+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); -+} -+ -+// Test Description: -+// Attempt to append an option to a packet that is large enough -+TEST_F (Dhcp6AppendOptionTest, ValidDataExpectSuccess) { -+ UINT8 *Cursor; -+ EFI_DHCP6_DUID *UntrustedDuid; -+ EFI_STATUS Status; -+ UINTN OriginalLength; -+ -+ UINT8 Duid[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; -+ -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+ OriginalLength = Packet->Length; -+ -+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID)); -+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL); -+ -+ UntrustedDuid->Length = NTOHS (sizeof (Duid)); -+ CopyMem (UntrustedDuid->Duid, Duid, sizeof (Duid)); -+ -+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option; -+ -+ Status = Dhcp6AppendOption ( -+ Dhcp6AppendOptionTest::Packet, -+ &Cursor, -+ HTONS (Dhcp6OptServerId), -+ UntrustedDuid->Length, -+ UntrustedDuid->Duid -+ ); -+ -+ ASSERT_EQ (Status, EFI_SUCCESS); -+ -+ // verify that the pointer to cursor moved by the expected amount -+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendOptionTest::Packet->Dhcp6.Option + sizeof (Duid) + 4); -+ -+ // verify that the length of the packet is now the expected amount -+ ASSERT_EQ (Dhcp6AppendOptionTest::Packet->Length, OriginalLength + sizeof (Duid) + 4); -+} -+ -+//////////////////////////////////////////////////////////////////////// -+// Dhcp6AppendETOption Tests -+//////////////////////////////////////////////////////////////////////// -+ -+class Dhcp6AppendETOptionTest : public ::testing::Test { -+public: -+ UINT8 *Buffer = NULL; -+ EFI_DHCP6_PACKET *Packet; -+ -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ // Initialize any resources or variables -+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); -+ ASSERT_NE (Buffer, (UINT8 *)NULL); -+ -+ Packet = (EFI_DHCP6_PACKET *)Buffer; -+ Packet->Size = DHCP6_PACKET_MAX_LEN; -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ // Clean up any resources or variables -+ if (Buffer != NULL) { -+ FreePool (Buffer); -+ } -+ } -+}; -+ -+// Test Description: -+// Attempt to append an option to a packet that is too small by a duid that is too large -+TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) { -+ UINT8 *Cursor; -+ EFI_STATUS Status; -+ DHCP6_INSTANCE Instance; -+ UINT16 ElapsedTimeVal; -+ UINT16 *ElapsedTime; -+ -+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option; -+ ElapsedTime = &ElapsedTimeVal; -+ -+ Packet->Length = Packet->Size - 2; -+ -+ Status = Dhcp6AppendETOption ( -+ Dhcp6AppendETOptionTest::Packet, -+ &Cursor, -+ &Instance, // Instance is not used in this function -+ &ElapsedTime -+ ); -+ -+ // verify that we error out because the packet is too small for the option header -+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); -+ -+ // reset the length -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+} -+ -+// Test Description: -+// Attempt to append an option to a packet that is large enough -+TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) { -+ UINT8 *Cursor; -+ EFI_STATUS Status; -+ DHCP6_INSTANCE Instance; -+ UINT16 ElapsedTimeVal; -+ UINT16 *ElapsedTime; -+ UINTN ExpectedSize; -+ UINTN OriginalLength; -+ -+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option; -+ ElapsedTime = &ElapsedTimeVal; -+ ExpectedSize = 6; -+ OriginalLength = Packet->Length; -+ -+ Status = Dhcp6AppendETOption ( -+ Dhcp6AppendETOptionTest::Packet, -+ &Cursor, -+ &Instance, // Instance is not used in this function -+ &ElapsedTime -+ ); -+ -+ // verify that the status is EFI_SUCCESS -+ ASSERT_EQ (Status, EFI_SUCCESS); -+ -+ // verify that the pointer to cursor moved by the expected amount -+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendETOptionTest::Packet->Dhcp6.Option + ExpectedSize); -+ -+ // verify that the length of the packet is now the expected amount -+ ASSERT_EQ (Dhcp6AppendETOptionTest::Packet->Length, OriginalLength + ExpectedSize); -+} -+ -+//////////////////////////////////////////////////////////////////////// -+// Dhcp6AppendIaOption Tests -+//////////////////////////////////////////////////////////////////////// -+ -+class Dhcp6AppendIaOptionTest : public ::testing::Test { -+public: -+ UINT8 *Buffer = NULL; -+ EFI_DHCP6_PACKET *Packet; -+ EFI_DHCP6_IA *Ia; -+ -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ // Initialize any resources or variables -+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); -+ ASSERT_NE (Buffer, (UINT8 *)NULL); -+ -+ Packet = (EFI_DHCP6_PACKET *)Buffer; -+ Packet->Size = DHCP6_PACKET_MAX_LEN; -+ -+ Ia = (EFI_DHCP6_IA *)AllocateZeroPool (sizeof (EFI_DHCP6_IA) + sizeof (EFI_DHCP6_IA_ADDRESS) * 2); -+ ASSERT_NE (Ia, (EFI_DHCP6_IA *)NULL); -+ -+ CopyMem (Ia->IaAddress, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS)); -+ CopyMem (Ia->IaAddress + 1, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS)); -+ -+ Ia->IaAddressCount = 2; -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ // Clean up any resources or variables -+ if (Buffer != NULL) { -+ FreePool (Buffer); -+ } -+ -+ if (Ia != NULL) { -+ FreePool (Ia); -+ } -+ } -+}; -+ -+// Test Description: -+// Attempt to append an option to a packet that doesn't have enough space -+// for the option header -+TEST_F (Dhcp6AppendIaOptionTest, IaNaInvalidDataExpectBufferTooSmall) { -+ UINT8 *Cursor; -+ EFI_STATUS Status; -+ -+ Packet->Length = Packet->Size - 2; -+ -+ Ia->Descriptor.Type = Dhcp6OptIana; -+ Ia->Descriptor.IaId = 0x12345678; -+ -+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; -+ -+ Status = Dhcp6AppendIaOption ( -+ Dhcp6AppendIaOptionTest::Packet, -+ &Cursor, -+ Ia, -+ 0x12345678, -+ 0x11111111, -+ Dhcp6OptIana -+ ); -+ -+ // verify that we error out because the packet is too small for the option header -+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); -+ -+ // reset the length -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+} -+ -+// Test Description: -+// Attempt to append an option to a packet that doesn't have enough space -+// for the option header -+TEST_F (Dhcp6AppendIaOptionTest, IaTaInvalidDataExpectBufferTooSmall) { -+ UINT8 *Cursor; -+ EFI_STATUS Status; -+ -+ // Use up nearly all the space in the packet -+ Packet->Length = Packet->Size - 2; -+ -+ Ia->Descriptor.Type = Dhcp6OptIata; -+ Ia->Descriptor.IaId = 0x12345678; -+ -+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; -+ -+ Status = Dhcp6AppendIaOption ( -+ Dhcp6AppendIaOptionTest::Packet, -+ &Cursor, -+ Ia, -+ 0, -+ 0, -+ Dhcp6OptIata -+ ); -+ -+ // verify that we error out because the packet is too small for the option header -+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); -+ -+ // reset the length -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+} -+ -+TEST_F (Dhcp6AppendIaOptionTest, IaNaValidDataExpectSuccess) { -+ UINT8 *Cursor; -+ EFI_STATUS Status; -+ UINTN ExpectedSize; -+ UINTN OriginalLength; -+ -+ // -+ // 2 bytes for the option header type -+ // -+ ExpectedSize = 2; -+ // -+ // 2 bytes for the option header length -+ // -+ ExpectedSize += 2; -+ // -+ // 4 bytes for the IAID -+ // -+ ExpectedSize += 4; -+ // -+ // + 4 bytes for the T1 -+ // -+ ExpectedSize += 4; -+ // -+ // + 4 bytes for the T2 -+ // -+ ExpectedSize += 4; -+ // -+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; -+ // + 2 bytes for the option header type -+ // + 2 bytes for the option header length -+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address -+ // -+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; -+ -+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; -+ -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+ OriginalLength = Packet->Length; -+ -+ Ia->Descriptor.Type = Dhcp6OptIana; -+ Ia->Descriptor.IaId = 0x12345678; -+ -+ Status = Dhcp6AppendIaOption ( -+ Dhcp6AppendIaOptionTest::Packet, -+ &Cursor, -+ Ia, -+ 0x12345678, -+ 0x12345678, -+ Dhcp6OptIana -+ ); -+ -+ // verify that the pointer to cursor moved by the expected amount -+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize); -+ -+ // verify that the length of the packet is now the expected amount -+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize); -+ -+ // verify that the status is EFI_SUCCESS -+ ASSERT_EQ (Status, EFI_SUCCESS); -+} -+ -+TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) { -+ UINT8 *Cursor; -+ EFI_STATUS Status; -+ UINTN ExpectedSize; -+ UINTN OriginalLength; -+ -+ // -+ // 2 bytes for the option header type -+ // -+ ExpectedSize = 2; -+ // -+ // 2 bytes for the option header length -+ // -+ ExpectedSize += 2; -+ // -+ // 4 bytes for the IAID -+ // -+ ExpectedSize += 4; -+ // -+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; -+ // + 2 bytes for the option header type -+ // + 2 bytes for the option header length -+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address -+ // -+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; -+ -+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; -+ -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+ OriginalLength = Packet->Length; -+ -+ Ia->Descriptor.Type = Dhcp6OptIata; -+ Ia->Descriptor.IaId = 0x12345678; -+ -+ Status = Dhcp6AppendIaOption ( -+ Dhcp6AppendIaOptionTest::Packet, -+ &Cursor, -+ Ia, -+ 0, -+ 0, -+ Dhcp6OptIata -+ ); -+ -+ // verify that the pointer to cursor moved by the expected amount -+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize); -+ -+ // verify that the length of the packet is now the expected amount -+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize); -+ -+ // verify that the status is EFI_SUCCESS -+ ASSERT_EQ (Status, EFI_SUCCESS); -+} -diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc -index b74b2048..7df011c9 100644 ---- a/NetworkPkg/Test/NetworkPkgHostTest.dsc -+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc -@@ -24,6 +24,7 @@ - # - # Build HOST_APPLICATION that tests NetworkPkg - # -+ NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf - - # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. - [LibraryClasses] --- -2.33.0 - diff --git a/0024-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch b/0024-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch deleted file mode 100644 index 7dc6f2ad81266dfad288050153884c58dd369763..0000000000000000000000000000000000000000 --- a/0024-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch +++ /dev/null @@ -1,602 +0,0 @@ -From 1f83cf107ce02b7b612bee89b3ad5a953c34a325 Mon Sep 17 00:00:00 2001 -From: "Doug Flick via groups.io" -Date: Fri, 26 Jan 2024 05:54:46 +0800 -Subject: [PATCH 04/19] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 - Patch - -REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534 - -Bug Details: -PixieFail Bug #1 -CVE-2023-45229 -CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N -CWE-125 Out-of-bounds Read - -Change Overview: - -Introduce Dhcp6SeekInnerOptionSafe which performs checks before seeking -the Inner Option from a DHCP6 Option. - -> -> EFI_STATUS -> Dhcp6SeekInnerOptionSafe ( -> IN UINT16 IaType, -> IN UINT8 *Option, -> IN UINT32 OptionLen, -> OUT UINT8 **IaInnerOpt, -> OUT UINT16 *IaInnerLen -> ); -> - -Lots of code cleanup to improve code readability. - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 138 +++++++++++++++++++--- - NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 203 +++++++++++++++++++++----------- - 2 files changed, 256 insertions(+), 85 deletions(-) - -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h -index 89c84a67..baa4eb66 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h -@@ -45,6 +45,20 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; - #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S') - #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I') - -+#define DHCP6_PACKET_ALL 0 -+#define DHCP6_PACKET_STATEFUL 1 -+#define DHCP6_PACKET_STATELESS 2 -+ -+#define DHCP6_BASE_PACKET_SIZE 1024 -+ -+#define DHCP6_PORT_CLIENT 546 -+#define DHCP6_PORT_SERVER 547 -+ -+#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) -+ -+#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE) -+#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE) -+ - // - // For more information on DHCP options see RFC 8415, Section 21.1 - // -@@ -59,12 +73,10 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; - // | (option-len octets) | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // --#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16)) --#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16)) -+#define DHCP6_SIZE_OF_OPT_CODE (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode)) -+#define DHCP6_SIZE_OF_OPT_LEN (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen)) - --// - // Combined size of Code and Length --// - #define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \ - DHCP6_SIZE_OF_OPT_LEN) - -@@ -73,34 +85,122 @@ STATIC_ASSERT ( - "Combined size of Code and Length must be 4 per RFC 8415" - ); - --// - // Offset to the length is just past the code --// --#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE) -+#define DHCP6_OFFSET_OF_OPT_LEN(a) (a + DHCP6_SIZE_OF_OPT_CODE) - STATIC_ASSERT ( -- DHCP6_OPT_LEN_OFFSET (0) == 2, -+ DHCP6_OFFSET_OF_OPT_LEN (0) == 2, - "Offset of length is + 2 past start of option" - ); - --#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) -+#define DHCP6_OFFSET_OF_OPT_DATA(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) - STATIC_ASSERT ( -- DHCP6_OPT_DATA_OFFSET (0) == 4, -+ DHCP6_OFFSET_OF_OPT_DATA (0) == 4, - "Offset to option data should be +4 from start of option" - ); -+// -+// Identity Association options (both NA (Non-Temporary) and TA (Temporary Association)) -+// are defined in RFC 8415 and are a deriviation of a TLV stucture -+// For more information on IA_NA see Section 21.4 -+// For more information on IA_TA see Section 21.5 -+// -+// -+// The format of IA_NA and IA_TA option: -+// -+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | OPTION_IA_NA | option-len | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | IAID (4 octets) | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | T1 (only for IA_NA) | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | T2 (only for IA_NA) | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | | -+// . IA_NA-options/IA_TA-options . -+// . . -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// -+#define DHCP6_SIZE_OF_IAID (sizeof(UINT32)) -+#define DHCP6_SIZE_OF_TIME_INTERVAL (sizeof(UINT32)) - --#define DHCP6_PACKET_ALL 0 --#define DHCP6_PACKET_STATEFUL 1 --#define DHCP6_PACKET_STATELESS 2 -+// Combined size of IAID, T1, and T2 -+#define DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 (DHCP6_SIZE_OF_IAID + \ -+ DHCP6_SIZE_OF_TIME_INTERVAL + \ -+ DHCP6_SIZE_OF_TIME_INTERVAL) -+STATIC_ASSERT ( -+ DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 == 12, -+ "Combined size of IAID, T1, T2 must be 12 per RFC 8415" -+ ); - --#define DHCP6_BASE_PACKET_SIZE 1024 -+// This is the size of IA_TA without options -+#define DHCP6_MIN_SIZE_OF_IA_TA (DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ -+ DHCP6_SIZE_OF_IAID) -+STATIC_ASSERT ( -+ DHCP6_MIN_SIZE_OF_IA_TA == 8, -+ "Minimum combined size of IA_TA per RFC 8415" -+ ); - --#define DHCP6_PORT_CLIENT 546 --#define DHCP6_PORT_SERVER 547 -+// Offset to a IA_TA inner option -+#define DHCP6_OFFSET_OF_IA_TA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_TA) -+STATIC_ASSERT ( -+ DHCP6_OFFSET_OF_IA_TA_INNER_OPT (0) == 8, -+ "Offset of IA_TA Inner option is + 8 past start of option" -+ ); - --#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) -+// This is the size of IA_NA without options (16) -+#define DHCP6_MIN_SIZE_OF_IA_NA DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ -+ DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 -+STATIC_ASSERT ( -+ DHCP6_MIN_SIZE_OF_IA_NA == 16, -+ "Minimum combined size of IA_TA per RFC 8415" -+ ); - --#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE) --#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE) -+#define DHCP6_OFFSET_OF_IA_NA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_NA) -+STATIC_ASSERT ( -+ DHCP6_OFFSET_OF_IA_NA_INNER_OPT (0) == 16, -+ "Offset of IA_NA Inner option is + 16 past start of option" -+ ); -+ -+#define DHCP6_OFFSET_OF_IA_NA_T1(a) (a + \ -+ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ -+ DHCP6_SIZE_OF_IAID) -+STATIC_ASSERT ( -+ DHCP6_OFFSET_OF_IA_NA_T1 (0) == 8, -+ "Offset of IA_NA Inner option is + 8 past start of option" -+ ); -+ -+#define DHCP6_OFFSET_OF_IA_NA_T2(a) (a + \ -+ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN +\ -+ DHCP6_SIZE_OF_IAID + \ -+ DHCP6_SIZE_OF_TIME_INTERVAL) -+STATIC_ASSERT ( -+ DHCP6_OFFSET_OF_IA_NA_T2 (0) == 12, -+ "Offset of IA_NA Inner option is + 12 past start of option" -+ ); -+ -+// -+// For more information see RFC 8415 Section 21.13 -+// -+// The format of the Status Code Option: -+// -+// 0 1 2 3 -+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | OPTION_STATUS_CODE | option-len | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | status-code | | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | -+// . . -+// . status-message . -+// . . -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// -+#define DHCP6_OFFSET_OF_STATUS_CODE(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) -+STATIC_ASSERT ( -+ DHCP6_OFFSET_OF_STATUS_CODE (0) == 4, -+ "Offset of status is + 4 past start of option" -+ ); - - extern EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress; - extern EFI_DHCP6_PROTOCOL gDhcp6ProtocolTemplate; -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -index bde2362c..99eb6b02 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -@@ -598,8 +598,8 @@ Dhcp6UpdateIaInfo ( - // The inner options still start with 2 bytes option-code and 2 bytes option-len. - // - if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { -- T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 8))); -- T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 12))); -+ T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); -+ T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); - // - // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2, - // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes -@@ -609,13 +609,14 @@ Dhcp6UpdateIaInfo ( - return EFI_DEVICE_ERROR; - } - -- IaInnerOpt = Option + 16; -- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2))) - 12); -+ IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); -+ IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); - } else { -- T1 = 0; -- T2 = 0; -- IaInnerOpt = Option + 8; -- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2))) - 4); -+ T1 = 0; -+ T2 = 0; -+ -+ IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); -+ IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID); - } - - // -@@ -641,7 +642,7 @@ Dhcp6UpdateIaInfo ( - Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); - - if (Option != NULL) { -- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4))); -+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); - if (StsCode != Dhcp6StsSuccess) { - return EFI_DEVICE_ERROR; - } -@@ -661,6 +662,87 @@ Dhcp6UpdateIaInfo ( - return Status; - } - -+/** -+ Seeks the Inner Options from a DHCP6 Option -+ -+ @param[in] IaType The type of the IA option. -+ @param[in] Option The pointer to the DHCP6 Option. -+ @param[in] OptionLen The length of the DHCP6 Option. -+ @param[out] IaInnerOpt The pointer to the IA inner option. -+ @param[out] IaInnerLen The length of the IA inner option. -+ -+ @retval EFI_SUCCESS Seek the inner option successfully. -+ @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, -+ the pointers are not modified -+**/ -+EFI_STATUS -+Dhcp6SeekInnerOptionSafe ( -+ IN UINT16 IaType, -+ IN UINT8 *Option, -+ IN UINT32 OptionLen, -+ OUT UINT8 **IaInnerOpt, -+ OUT UINT16 *IaInnerLen -+ ) -+{ -+ UINT16 IaInnerLenTmp; -+ UINT8 *IaInnerOptTmp; -+ -+ if (Option == NULL) { -+ ASSERT (Option != NULL); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ if (IaInnerOpt == NULL) { -+ ASSERT (IaInnerOpt != NULL); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ if (IaInnerLen == NULL) { -+ ASSERT (IaInnerLen != NULL); -+ return EFI_DEVICE_ERROR; -+ } -+ -+ if (IaType == Dhcp6OptIana) { -+ // Verify we have a fully formed IA_NA -+ if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); -+ -+ // Verify the IaInnerLen is valid. -+ IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); -+ if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { -+ return EFI_DEVICE_ERROR; -+ } -+ -+ IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; -+ } else if (IaType == Dhcp6OptIata) { -+ // Verify the OptionLen is valid. -+ if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { -+ return EFI_DEVICE_ERROR; -+ } -+ -+ IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); -+ -+ // Verify the IaInnerLen is valid. -+ IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); -+ if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { -+ return EFI_DEVICE_ERROR; -+ } -+ -+ IaInnerLenTmp -= DHCP6_SIZE_OF_IAID; -+ } else { -+ return EFI_DEVICE_ERROR; -+ } -+ -+ *IaInnerOpt = IaInnerOptTmp; -+ *IaInnerLen = IaInnerLenTmp; -+ -+ return EFI_SUCCESS; -+} -+ - /** - Seek StatusCode Option in package. A Status Code option may appear in the - options field of a DHCP message and/or in the options field of another option. -@@ -684,6 +766,12 @@ Dhcp6SeekStsOption ( - UINT8 *IaInnerOpt; - UINT16 IaInnerLen; - UINT16 StsCode; -+ UINT32 OptionLen; -+ -+ // OptionLen is the length of the Options excluding the DHCP header. -+ // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last -+ // byte of the Option[] field. -+ OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); - - // - // Seek StatusCode option directly in DHCP message body. That is, search in -@@ -691,12 +779,12 @@ Dhcp6SeekStsOption ( - // - *Option = Dhcp6SeekOption ( - Packet->Dhcp6.Option, -- Packet->Length - 4, -+ OptionLen, - Dhcp6OptStatusCode - ); - - if (*Option != NULL) { -- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4))); -+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option)))); - if (StsCode != Dhcp6StsSuccess) { - return EFI_DEVICE_ERROR; - } -@@ -707,7 +795,7 @@ Dhcp6SeekStsOption ( - // - *Option = Dhcp6SeekIaOption ( - Packet->Dhcp6.Option, -- Packet->Length - sizeof (EFI_DHCP6_HEADER), -+ OptionLen, - &Instance->Config->IaDescriptor - ); - if (*Option == NULL) { -@@ -715,52 +803,35 @@ Dhcp6SeekStsOption ( - } - - // -- // The format of the IA_NA option is: -+ // Calculate the distance from Packet->Dhcp6.Option to the IA option. - // -- // 0 1 2 3 -- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | OPTION_IA_NA | option-len | -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | IAID (4 octets) | -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | T1 | -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | T2 | -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | | -- // . IA_NA-options . -- // . . -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is -+ // the size of the whole packet, including the DHCP header, and Packet->Length -+ // is the length of the DHCP message body, excluding the DHCP header. - // -- // The format of the IA_TA option is: -+ // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of -+ // DHCP6 option area to the start of the IA option. - // -- // 0 1 2 3 -- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | OPTION_IA_TA | option-len | -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | IAID (4 octets) | -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- // | | -- // . IA_TA-options . -- // . . -- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the -+ // IA option to the end of the DHCP6 option area, thus subtract the space -+ // up until this option - // -+ OptionLen = OptionLen - (*Option - Packet->Dhcp6.Option); - - // -- // sizeof (option-code + option-len + IaId) = 8 -- // sizeof (option-code + option-len + IaId + T1) = 12 -- // sizeof (option-code + option-len + IaId + T1 + T2) = 16 -+ // Seek the inner option - // -- // The inner options still start with 2 bytes option-code and 2 bytes option-len. -- // -- if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { -- IaInnerOpt = *Option + 16; -- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2))) - 12); -- } else { -- IaInnerOpt = *Option + 8; -- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2))) - 4); -+ if (EFI_ERROR ( -+ Dhcp6SeekInnerOptionSafe ( -+ Instance->Config->IaDescriptor.Type, -+ *Option, -+ OptionLen, -+ &IaInnerOpt, -+ &IaInnerLen -+ ) -+ )) -+ { -+ return EFI_DEVICE_ERROR; - } - - // -@@ -784,7 +855,7 @@ Dhcp6SeekStsOption ( - // - *Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); - if (*Option != NULL) { -- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4))); -+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option))))); - if (StsCode != Dhcp6StsSuccess) { - return EFI_DEVICE_ERROR; - } -@@ -1105,7 +1176,7 @@ Dhcp6SendRequestMsg ( - // - Option = Dhcp6SeekOption ( - Instance->AdSelect->Dhcp6.Option, -- Instance->AdSelect->Length - 4, -+ Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptServerId - ); - if (Option == NULL) { -@@ -1289,7 +1360,7 @@ Dhcp6SendDeclineMsg ( - // - Option = Dhcp6SeekOption ( - LastReply->Dhcp6.Option, -- LastReply->Length - 4, -+ LastReply->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptServerId - ); - if (Option == NULL) { -@@ -1448,7 +1519,7 @@ Dhcp6SendReleaseMsg ( - // - Option = Dhcp6SeekOption ( - LastReply->Dhcp6.Option, -- LastReply->Length - 4, -+ LastReply->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptServerId - ); - if (Option == NULL) { -@@ -1673,7 +1744,7 @@ Dhcp6SendRenewRebindMsg ( - - Option = Dhcp6SeekOption ( - LastReply->Dhcp6.Option, -- LastReply->Length - 4, -+ LastReply->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptServerId - ); - if (Option == NULL) { -@@ -2208,7 +2279,7 @@ Dhcp6HandleReplyMsg ( - // - Option = Dhcp6SeekOption ( - Packet->Dhcp6.Option, -- Packet->Length - 4, -+ Packet->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptRapidCommit - ); - -@@ -2354,7 +2425,7 @@ Dhcp6HandleReplyMsg ( - // - // Any error status code option is found. - // -- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4))); -+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option))))); - switch (StsCode) { - case Dhcp6StsUnspecFail: - // -@@ -2487,7 +2558,7 @@ Dhcp6SelectAdvertiseMsg ( - // - Option = Dhcp6SeekOption ( - AdSelect->Dhcp6.Option, -- AdSelect->Length - 4, -+ AdSelect->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptServerUnicast - ); - -@@ -2498,7 +2569,7 @@ Dhcp6SelectAdvertiseMsg ( - return EFI_OUT_OF_RESOURCES; - } - -- CopyMem (Instance->Unicast, Option + 4, sizeof (EFI_IPv6_ADDRESS)); -+ CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS)); - } - - // -@@ -2551,7 +2622,7 @@ Dhcp6HandleAdvertiseMsg ( - // - Option = Dhcp6SeekOption ( - Packet->Dhcp6.Option, -- Packet->Length - 4, -+ Packet->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptRapidCommit - ); - -@@ -2645,7 +2716,7 @@ Dhcp6HandleAdvertiseMsg ( - CopyMem (Instance->AdSelect, Packet, Packet->Size); - - if (Option != NULL) { -- Instance->AdPref = *(Option + 4); -+ Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option)); - } - } else { - // -@@ -2714,11 +2785,11 @@ Dhcp6HandleStateful ( - // - Option = Dhcp6SeekOption ( - Packet->Dhcp6.Option, -- Packet->Length - 4, -+ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, - Dhcp6OptClientId - ); - -- if ((Option == NULL) || (CompareMem (Option + 4, ClientId->Duid, ClientId->Length) != 0)) { -+ if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) { - goto ON_CONTINUE; - } - -@@ -2727,7 +2798,7 @@ Dhcp6HandleStateful ( - // - Option = Dhcp6SeekOption ( - Packet->Dhcp6.Option, -- Packet->Length - 4, -+ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, - Dhcp6OptServerId - ); - -@@ -2832,7 +2903,7 @@ Dhcp6HandleStateless ( - // - Option = Dhcp6SeekOption ( - Packet->Dhcp6.Option, -- Packet->Length - 4, -+ Packet->Length - sizeof (EFI_DHCP6_HEADER), - Dhcp6OptServerId - ); - --- -2.33.0 - diff --git a/0025-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch b/0025-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch deleted file mode 100644 index ec44d8fbdad06a8e6cf33f812b7db5438afe2ee6..0000000000000000000000000000000000000000 --- a/0025-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch +++ /dev/null @@ -1,549 +0,0 @@ -From 21230943a0fd18672929f3be7df2a351f4ba5fc1 Mon Sep 17 00:00:00 2001 -From: "Doug Flick via groups.io" -Date: Fri, 26 Jan 2024 05:54:47 +0800 -Subject: [PATCH 05/19] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 - Unit Tests - -REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534 - -These tests confirm that the report bug... - -"Out-of-bounds read when processing IA_NA/IA_TA options in a -DHCPv6 Advertise message" - -..has been patched. - -The following functions are tested to confirm an out of bounds read is -patched and that the correct statuses are returned: - -Dhcp6SeekInnerOptionSafe -Dhcp6SeekStsOption - -TCBZ4534 -CVE-2023-45229 -CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N -CWE-125 Out-of-bounds Read - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 2 +- - .../GoogleTest/Dhcp6DxeGoogleTest.inf | 1 + - .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 365 +++++++++++++++++- - .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h | 58 +++ - NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + - 5 files changed, 424 insertions(+), 3 deletions(-) - create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h - -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -index 99eb6b02..afec4eff 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -@@ -816,7 +816,7 @@ Dhcp6SeekStsOption ( - // IA option to the end of the DHCP6 option area, thus subtract the space - // up until this option - // -- OptionLen = OptionLen - (*Option - Packet->Dhcp6.Option); -+ OptionLen = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option); - - // - // Seek the inner option -diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf -index 253c61e8..94ebdf63 100644 ---- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf -+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf -@@ -18,6 +18,7 @@ - [Sources] - Dhcp6DxeGoogleTest.cpp - Dhcp6IoGoogleTest.cpp -+ Dhcp6IoGoogleTest.h - ../Dhcp6Io.c - ../Dhcp6Utility.c - -diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp -index a2b8a9f8..3bb70371 100644 ---- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp -+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp -@@ -13,6 +13,7 @@ extern "C" { - #include - #include "../Dhcp6Impl.h" - #include "../Dhcp6Utility.h" -+ #include "Dhcp6IoGoogleTest.h" - } - - //////////////////////////////////////////////////////////////////////// -@@ -21,7 +22,35 @@ extern "C" { - - #define DHCP6_PACKET_MAX_LEN 1500 - -+// This definition is used by this test but is also required to compile -+// by Dhcp6Io.c -+#define DHCPV6_OPTION_IA_NA 3 -+#define DHCPV6_OPTION_IA_TA 4 -+ -+#define SEARCH_PATTERN 0xDEADC0DE -+#define SEARCH_PATTERN_LEN sizeof(SEARCH_PATTERN) -+ - //////////////////////////////////////////////////////////////////////// -+// Test structures for IA_NA and IA_TA options -+//////////////////////////////////////////////////////////////////////// -+typedef struct { -+ UINT16 Code; -+ UINT16 Len; -+ UINT32 IAID; -+} DHCPv6_OPTION; -+ -+typedef struct { -+ DHCPv6_OPTION Header; -+ UINT32 T1; -+ UINT32 T2; -+ UINT8 InnerOptions[0]; -+} DHCPv6_OPTION_IA_NA; -+ -+typedef struct { -+ DHCPv6_OPTION Header; -+ UINT8 InnerOptions[0]; -+} DHCPv6_OPTION_IA_TA; -+ - //////////////////////////////////////////////////////////////////////// - // Symbol Definitions - // These functions are not directly under test - but required to compile -@@ -210,7 +239,7 @@ TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) { - Status = Dhcp6AppendETOption ( - Dhcp6AppendETOptionTest::Packet, - &Cursor, -- &Instance, // Instance is not used in this function -+ &Instance, // Instance is not used in this function - &ElapsedTime - ); - -@@ -240,7 +269,7 @@ TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) { - Status = Dhcp6AppendETOption ( - Dhcp6AppendETOptionTest::Packet, - &Cursor, -- &Instance, // Instance is not used in this function -+ &Instance, // Instance is not used in this function - &ElapsedTime - ); - -@@ -476,3 +505,335 @@ TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) { - // verify that the status is EFI_SUCCESS - ASSERT_EQ (Status, EFI_SUCCESS); - } -+ -+//////////////////////////////////////////////////////////////////////// -+// Dhcp6SeekInnerOptionSafe Tests -+//////////////////////////////////////////////////////////////////////// -+ -+// Define a fixture for your tests if needed -+class Dhcp6SeekInnerOptionSafeTest : public ::testing::Test { -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ // Initialize any resources or variables -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ // Clean up any resources or variables -+ } -+}; -+ -+// Test Description: -+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IANA option is found. -+TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAValidOptionExpectSuccess) { -+ EFI_STATUS Result; -+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 }; -+ UINT32 OptionLength = sizeof (Option); -+ DHCPv6_OPTION_IA_NA *OptionPtr = (DHCPv6_OPTION_IA_NA *)Option; -+ UINT32 SearchPattern = SEARCH_PATTERN; -+ -+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; -+ UINT8 *InnerOptionPtr = NULL; -+ UINT16 InnerOptionLength = 0; -+ -+ OptionPtr->Header.Code = Dhcp6OptIana; -+ OptionPtr->Header.Len = HTONS (4 + 12); // Valid length has to be more than 12 -+ OptionPtr->Header.IAID = 0x12345678; -+ OptionPtr->T1 = 0x11111111; -+ OptionPtr->T2 = 0x22222222; -+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); -+ -+ Result = Dhcp6SeekInnerOptionSafe ( -+ Dhcp6OptIana, -+ Option, -+ OptionLength, -+ &InnerOptionPtr, -+ &InnerOptionLength -+ ); -+ ASSERT_EQ (Result, EFI_SUCCESS); -+ ASSERT_EQ (InnerOptionLength, 4); -+ ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0); -+} -+ -+// Test Description: -+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_DEIVCE_ERROR when the IANA option size is invalid. -+TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAInvalidSizeExpectFail) { -+ // Lets add an inner option of bytes we expect to find -+ EFI_STATUS Status; -+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 }; -+ UINT32 OptionLength = sizeof (Option); -+ DHCPv6_OPTION_IA_NA *OptionPtr = (DHCPv6_OPTION_IA_NA *)Option; -+ UINT32 SearchPattern = SEARCH_PATTERN; -+ -+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; -+ UINT8 *InnerOptionPtr = NULL; -+ UINT16 InnerOptionLength = 0; -+ -+ OptionPtr->Header.Code = Dhcp6OptIana; -+ OptionPtr->Header.Len = HTONS (4); // Set the length to lower than expected (12) -+ OptionPtr->Header.IAID = 0x12345678; -+ OptionPtr->T1 = 0x11111111; -+ OptionPtr->T2 = 0x22222222; -+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); -+ -+ // Set the InnerOptionLength to be less than the size of the option -+ Status = Dhcp6SeekInnerOptionSafe ( -+ Dhcp6OptIana, -+ Option, -+ OptionLength, -+ &InnerOptionPtr, -+ &InnerOptionLength -+ ); -+ ASSERT_EQ (Status, EFI_DEVICE_ERROR); -+ -+ // Now set the OptionLength to be less than the size of the option -+ OptionLength = sizeof (DHCPv6_OPTION_IA_NA) - 1; -+ Status = Dhcp6SeekInnerOptionSafe ( -+ Dhcp6OptIana, -+ Option, -+ OptionLength, -+ &InnerOptionPtr, -+ &InnerOptionLength -+ ); -+ ASSERT_EQ (Status, EFI_DEVICE_ERROR); -+} -+ -+// Test Description: -+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option is found -+TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAValidOptionExpectSuccess) { -+ // Lets add an inner option of bytes we expect to find -+ EFI_STATUS Status; -+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 }; -+ UINT32 OptionLength = sizeof (Option); -+ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option; -+ UINT32 SearchPattern = SEARCH_PATTERN; -+ -+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; -+ UINT8 *InnerOptionPtr = NULL; -+ UINT16 InnerOptionLength = 0; -+ -+ OptionPtr->Header.Code = Dhcp6OptIata; -+ OptionPtr->Header.Len = HTONS (4 + 4); // Valid length has to be more than 4 -+ OptionPtr->Header.IAID = 0x12345678; -+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); -+ -+ Status = Dhcp6SeekInnerOptionSafe ( -+ Dhcp6OptIata, -+ Option, -+ OptionLength, -+ &InnerOptionPtr, -+ &InnerOptionLength -+ ); -+ ASSERT_EQ (Status, EFI_SUCCESS); -+ ASSERT_EQ (InnerOptionLength, 4); -+ ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0); -+} -+ -+// Test Description: -+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid. -+TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAInvalidSizeExpectFail) { -+ // Lets add an inner option of bytes we expect to find -+ EFI_STATUS Status; -+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 }; -+ UINT32 OptionLength = sizeof (Option); -+ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option; -+ UINT32 SearchPattern = SEARCH_PATTERN; -+ -+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; -+ UINT8 *InnerOptionPtr = NULL; -+ UINT16 InnerOptionLength = 0; -+ -+ OptionPtr->Header.Code = Dhcp6OptIata; -+ OptionPtr->Header.Len = HTONS (2); // Set the length to lower than expected (4) -+ OptionPtr->Header.IAID = 0x12345678; -+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); -+ -+ Status = Dhcp6SeekInnerOptionSafe ( -+ Dhcp6OptIata, -+ Option, -+ OptionLength, -+ &InnerOptionPtr, -+ &InnerOptionLength -+ ); -+ ASSERT_EQ (Status, EFI_DEVICE_ERROR); -+ -+ // Now lets try modifying the OptionLength to be less than the size of the option -+ OptionLength = sizeof (DHCPv6_OPTION_IA_TA) - 1; -+ Status = Dhcp6SeekInnerOptionSafe ( -+ Dhcp6OptIata, -+ Option, -+ OptionLength, -+ &InnerOptionPtr, -+ &InnerOptionLength -+ ); -+ ASSERT_EQ (Status, EFI_DEVICE_ERROR); -+} -+ -+// Test Description: -+// This test verifies that any other Option Type fails -+TEST_F (Dhcp6SeekInnerOptionSafeTest, InvalidOption) { -+ // Lets add an inner option of bytes we expect to find -+ EFI_STATUS Result; -+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 }; -+ UINT32 OptionLength = sizeof (Option); -+ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option; -+ UINT32 SearchPattern = SEARCH_PATTERN; -+ -+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; -+ UINT8 *InnerOptionPtr = NULL; -+ UINT16 InnerOptionLength = 0; -+ -+ OptionPtr->Header.Code = 0xC0DE; -+ OptionPtr->Header.Len = HTONS (2); // Set the length to lower than expected (4) -+ OptionPtr->Header.IAID = 0x12345678; -+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); -+ -+ Result = Dhcp6SeekInnerOptionSafe (0xC0DE, Option, OptionLength, &InnerOptionPtr, &InnerOptionLength); -+ ASSERT_EQ (Result, EFI_DEVICE_ERROR); -+} -+ -+//////////////////////////////////////////////////////////////////////// -+// Dhcp6SeekStsOption Tests -+//////////////////////////////////////////////////////////////////////// -+ -+#define PACKET_SIZE (1500) -+ -+class Dhcp6SeekStsOptionTest : public ::testing::Test { -+public: -+ DHCP6_INSTANCE Instance = { 0 }; -+ EFI_DHCP6_PACKET *Packet = NULL; -+ EFI_DHCP6_CONFIG_DATA Config = { 0 }; -+ -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ // Allocate a packet -+ Packet = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); -+ ASSERT_NE (Packet, nullptr); -+ -+ // Initialize the packet -+ Packet->Size = PACKET_SIZE; -+ -+ Instance.Config = &Config; -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ // Clean up any resources or variables -+ FreePool (Packet); -+ } -+}; -+ -+// Test Description: -+// This test verifies that Dhcp6SeekStsOption returns EFI_DEVICE_ERROR when the option is invalid -+// This verifies that the calling function is working as expected -+TEST_F (Dhcp6SeekStsOptionTest, SeekIATAOptionExpectFail) { -+ EFI_STATUS Status; -+ UINT8 *Option = NULL; -+ UINT32 SearchPattern = SEARCH_PATTERN; -+ UINT16 SearchPatternLength = SEARCH_PATTERN_LEN; -+ UINT16 *Len = NULL; -+ EFI_DHCP6_IA Ia = { 0 }; -+ -+ Ia.Descriptor.Type = DHCPV6_OPTION_IA_TA; -+ Ia.IaAddressCount = 1; -+ Ia.IaAddress[0].PreferredLifetime = 0xDEADBEEF; -+ Ia.IaAddress[0].ValidLifetime = 0xDEADAAAA; -+ Ia.IaAddress[0].IpAddress = mAllDhcpRelayAndServersAddress; -+ -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+ -+ Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option; -+ -+ // Let's append the option to the packet -+ Status = Dhcp6AppendOption ( -+ Dhcp6SeekStsOptionTest::Packet, -+ &Option, -+ Dhcp6OptStatusCode, -+ SearchPatternLength, -+ (UINT8 *)&SearchPattern -+ ); -+ ASSERT_EQ (Status, EFI_SUCCESS); -+ -+ // Inner option length - this will be overwritten later -+ Len = (UINT16 *)(Option + 2); -+ -+ // Fill in the inner IA option -+ Status = Dhcp6AppendIaOption ( -+ Dhcp6SeekStsOptionTest::Packet, -+ &Option, -+ &Ia, -+ 0x12345678, -+ 0x11111111, -+ 0x22222222 -+ ); -+ ASSERT_EQ (Status, EFI_SUCCESS); -+ -+ // overwrite the len of inner Ia option -+ *Len = HTONS (3); -+ -+ Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_TA; -+ -+ Option = NULL; -+ Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option); -+ -+ ASSERT_EQ (Status, EFI_DEVICE_ERROR); -+} -+ -+// Test Description: -+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid. -+TEST_F (Dhcp6SeekStsOptionTest, SeekIANAOptionExpectSuccess) { -+ EFI_STATUS Status = EFI_NOT_FOUND; -+ UINT8 *Option = NULL; -+ UINT32 SearchPattern = SEARCH_PATTERN; -+ UINT16 SearchPatternLength = SEARCH_PATTERN_LEN; -+ EFI_DHCP6_IA Ia = { 0 }; -+ -+ Ia.Descriptor.Type = DHCPV6_OPTION_IA_NA; -+ Ia.IaAddressCount = 1; -+ Ia.IaAddress[0].PreferredLifetime = 0x11111111; -+ Ia.IaAddress[0].ValidLifetime = 0x22222222; -+ Ia.IaAddress[0].IpAddress = mAllDhcpRelayAndServersAddress; -+ Packet->Length = sizeof (EFI_DHCP6_HEADER); -+ -+ Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option; -+ -+ Status = Dhcp6AppendOption ( -+ Dhcp6SeekStsOptionTest::Packet, -+ &Option, -+ Dhcp6OptStatusCode, -+ SearchPatternLength, -+ (UINT8 *)&SearchPattern -+ ); -+ ASSERT_EQ (Status, EFI_SUCCESS); -+ -+ Status = Dhcp6AppendIaOption ( -+ Dhcp6SeekStsOptionTest::Packet, -+ &Option, -+ &Ia, -+ 0x12345678, -+ 0x11111111, -+ 0x22222222 -+ ); -+ ASSERT_EQ (Status, EFI_SUCCESS); -+ -+ Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_NA; -+ -+ Option = NULL; -+ Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option); -+ -+ ASSERT_EQ (Status, EFI_SUCCESS); -+} -diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h -new file mode 100644 -index 00000000..6801106a ---- /dev/null -+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h -@@ -0,0 +1,58 @@ -+/** @file -+ Acts as header for private functions under test in Dhcp6Io.c -+ -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+ -+#ifndef DHCP6_IO_GOOGLE_TEST_H_ -+#define DHCP6_IO_GOOGLE_TEST_H_ -+ -+//////////////////////////////////////////////////////////////////////////////// -+// These are the functions that are being unit tested -+//////////////////////////////////////////////////////////////////////////////// -+ -+#include -+ -+/** -+ Seeks the Inner Options from a DHCP6 Option -+ -+ @param[in] IaType The type of the IA option. -+ @param[in] Option The pointer to the DHCP6 Option. -+ @param[in] OptionLen The length of the DHCP6 Option. -+ @param[out] IaInnerOpt The pointer to the IA inner option. -+ @param[out] IaInnerLen The length of the IA inner option. -+ -+ @retval EFI_SUCCESS Seek the inner option successfully. -+ @retval EFI_DEVICE_ERROR The OptionLen is invalid. -+*/ -+EFI_STATUS -+Dhcp6SeekInnerOptionSafe ( -+ UINT16 IaType, -+ UINT8 *Option, -+ UINT32 OptionLen, -+ UINT8 **IaInnerOpt, -+ UINT16 *IaInnerLen -+ ); -+ -+/** -+ Seek StatusCode Option in package. A Status Code option may appear in the -+ options field of a DHCP message and/or in the options field of another option. -+ See details in section 22.13, RFC3315. -+ -+ @param[in] Instance The pointer to the Dhcp6 instance. -+ @param[in] Packet The pointer to reply messages. -+ @param[out] Option The pointer to status code option. -+ -+ @retval EFI_SUCCESS Seek status code option successfully. -+ @retval EFI_DEVICE_ERROR An unexpected error. -+ -+**/ -+EFI_STATUS -+Dhcp6SeekStsOption ( -+ IN DHCP6_INSTANCE *Instance, -+ IN EFI_DHCP6_PACKET *Packet, -+ OUT UINT8 **Option -+ ); -+ -+#endif // DHCP6_IO_GOOGLE_TEST_H -diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc -index 7df011c9..e49b78f5 100644 ---- a/NetworkPkg/Test/NetworkPkgHostTest.dsc -+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc -@@ -16,6 +16,7 @@ - SKUID_IDENTIFIER = DEFAULT - - !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc -+ - [Packages] - MdePkg/MdePkg.dec - UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec --- -2.33.0 - diff --git a/0026-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch b/0026-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch deleted file mode 100644 index 54183b4ccb635e00670ccfc7173c6ee3cf78c70e..0000000000000000000000000000000000000000 --- a/0026-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e5b0312aae033a90d4c5be31daead52549edf2f9 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:48 +0800 -Subject: [PATCH 06/19] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Patch - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4536 - -Bug Overview: -PixieFail Bug #3 -CVE-2023-45231 -CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N -CWE-125 Out-of-bounds Read - -Out-of-bounds read when handling a ND Redirect message with truncated -options - -Change Overview: - -Adds a check to prevent truncated options from being parsed -+ // -+ // Cannot process truncated options. -+ // Cannot process options with a length of 0 as there is no Type -field. -+ // -+ if (OptionLen < sizeof (IP6_OPTION_HEADER)) { -+ return FALSE; -+ } - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/Ip6Dxe/Ip6Option.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c -index 199eea12..780771f2 100644 ---- a/NetworkPkg/Ip6Dxe/Ip6Option.c -+++ b/NetworkPkg/Ip6Dxe/Ip6Option.c -@@ -137,6 +137,14 @@ Ip6IsNDOptionValid ( - return FALSE; - } - -+ // -+ // Cannot process truncated options. -+ // Cannot process options with a length of 0 as there is no Type field. -+ // -+ if (OptionLen < sizeof (IP6_OPTION_HEADER)) { -+ return FALSE; -+ } -+ - Offset = 0; - - // --- -2.33.0 - diff --git a/0027-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch b/0027-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch deleted file mode 100644 index 3282b8816d1520a30ef12cb8e139499000b3afc7..0000000000000000000000000000000000000000 --- a/0027-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 018667d67d19f904d0783c3dd7db3514cec9f873 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:49 +0800 -Subject: [PATCH 07/19] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Unit - Tests - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4536 - -Validates that the patch for... - -Out-of-bounds read when handling a ND Redirect message with truncated -options - -.. has been fixed - -Tests the following function to ensure that an out of bounds read does -not occur -Ip6OptionValidation - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp | 20 +++ - .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 42 ++++++ - .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 129 ++++++++++++++++++ - NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + - 4 files changed, 192 insertions(+) - create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp - create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf - create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp - -diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp -new file mode 100644 -index 00000000..9fd81d9c ---- /dev/null -+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp -@@ -0,0 +1,20 @@ -+/** @file -+ Acts as the main entry point for the tests for the Ip6Dxe module. -+ -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+ -+//////////////////////////////////////////////////////////////////////////////// -+// Run the tests -+//////////////////////////////////////////////////////////////////////////////// -+int -+main ( -+ int argc, -+ char *argv[] -+ ) -+{ -+ testing::InitGoogleTest (&argc, argv); -+ return RUN_ALL_TESTS (); -+} -diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf -new file mode 100644 -index 00000000..60396b05 ---- /dev/null -+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf -@@ -0,0 +1,42 @@ -+## @file -+# Unit test suite for the Ip6Dxe using Google Test -+# -+# Copyright (c) Microsoft Corporation.
-+# SPDX-License-Identifier: BSD-2-Clause-Patent -+## -+[Defines] -+ INF_VERSION = 0x00010017 -+ BASE_NAME = Ip6DxeUnitTest -+ FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A -+ VERSION_STRING = 1.0 -+ MODULE_TYPE = HOST_APPLICATION -+# -+# The following information is for reference only and not required by the build tools. -+# -+# VALID_ARCHITECTURES = IA32 X64 AARCH64 -+# -+[Sources] -+ Ip6DxeGoogleTest.cpp -+ Ip6OptionGoogleTest.cpp -+ ../Ip6Option.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ MdeModulePkg/MdeModulePkg.dec -+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec -+ NetworkPkg/NetworkPkg.dec -+ -+[LibraryClasses] -+ GoogleTestLib -+ DebugLib -+ NetLib -+ PcdLib -+ -+[Protocols] -+ gEfiDhcp6ServiceBindingProtocolGuid -+ -+[Pcd] -+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType -+ -+[Guids] -+ gZeroGuid -diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp -new file mode 100644 -index 00000000..874400eb ---- /dev/null -+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp -@@ -0,0 +1,129 @@ -+/** @file -+ Tests for Ip6Option.c. -+ -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+ -+extern "C" { -+ #include -+ #include -+ #include -+ #include "../Ip6Impl.h" -+ #include "../Ip6Option.h" -+} -+ -+///////////////////////////////////////////////////////////////////////// -+// Defines -+/////////////////////////////////////////////////////////////////////// -+ -+#define IP6_PREFIX_INFO_OPTION_DATA_LEN 32 -+#define OPTION_HEADER_IP6_PREFIX_DATA_LEN (sizeof (IP6_OPTION_HEADER) + IP6_PREFIX_INFO_OPTION_DATA_LEN) -+ -+//////////////////////////////////////////////////////////////////////// -+// Symbol Definitions -+// These functions are not directly under test - but required to compile -+//////////////////////////////////////////////////////////////////////// -+UINT32 mIp6Id; -+ -+EFI_STATUS -+Ip6SendIcmpError ( -+ IN IP6_SERVICE *IpSb, -+ IN NET_BUF *Packet, -+ IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, -+ IN EFI_IPv6_ADDRESS *DestinationAddress, -+ IN UINT8 Type, -+ IN UINT8 Code, -+ IN UINT32 *Pointer OPTIONAL -+ ) -+{ -+ // .. -+ return EFI_SUCCESS; -+} -+ -+//////////////////////////////////////////////////////////////////////// -+// Ip6OptionValidation Tests -+//////////////////////////////////////////////////////////////////////// -+ -+// Define a fixture for your tests if needed -+class Ip6OptionValidationTest : public ::testing::Test { -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ // Initialize any resources or variables -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ // Clean up any resources or variables -+ } -+}; -+ -+// Test Description: -+// Null option should return false -+TEST_F (Ip6OptionValidationTest, NullOptionShouldReturnFalse) { -+ UINT8 *option = nullptr; -+ UINT16 optionLen = 10; // Provide a suitable length -+ -+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); -+} -+ -+// Test Description: -+// Truncated option should return false -+TEST_F (Ip6OptionValidationTest, TruncatedOptionShouldReturnFalse) { -+ UINT8 option[] = { 0x01 }; // Provide a truncated option -+ UINT16 optionLen = 1; -+ -+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); -+} -+ -+// Test Description: -+// Ip6OptionPrefixInfo Option with zero length should return false -+TEST_F (Ip6OptionValidationTest, OptionWithZeroLengthShouldReturnFalse) { -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = Ip6OptionPrefixInfo; -+ optionHeader.Length = 0; -+ UINT8 option[sizeof (IP6_OPTION_HEADER)]; -+ -+ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); -+ UINT16 optionLen = sizeof (IP6_OPTION_HEADER); -+ -+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); -+} -+ -+// Test Description: -+// Ip6OptionPrefixInfo Option with valid length should return true -+TEST_F (Ip6OptionValidationTest, ValidPrefixInfoOptionShouldReturnTrue) { -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = Ip6OptionPrefixInfo; -+ optionHeader.Length = 4; // Length 4 * 8 = 32 -+ UINT8 option[OPTION_HEADER_IP6_PREFIX_DATA_LEN]; -+ -+ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); -+ -+ EXPECT_TRUE (Ip6IsNDOptionValid (option, IP6_PREFIX_INFO_OPTION_DATA_LEN)); -+} -+ -+// Test Description: -+// Ip6OptionPrefixInfo Option with invalid length should return false -+TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse) { -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = Ip6OptionPrefixInfo; -+ optionHeader.Length = 3; // Length 3 * 8 = 24 (Invalid) -+ UINT8 option[sizeof (IP6_OPTION_HEADER)]; -+ -+ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); -+ UINT16 optionLen = sizeof (IP6_OPTION_HEADER); -+ -+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); -+} -diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc -index e49b78f5..b4ea0a77 100644 ---- a/NetworkPkg/Test/NetworkPkgHostTest.dsc -+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc -@@ -26,6 +26,7 @@ - # Build HOST_APPLICATION that tests NetworkPkg - # - NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf -+ NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf - - # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. - [LibraryClasses] --- -2.33.0 - diff --git a/0028-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch b/0028-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch deleted file mode 100644 index 24b6240b541c51cbb29c17b46c67ab9c1f943cf8..0000000000000000000000000000000000000000 --- a/0028-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch +++ /dev/null @@ -1,357 +0,0 @@ -From a4cd07ec236bf0ae79a9431d22069dbd0241a3cc Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:50 +0800 -Subject: [PATCH 08/19] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537 -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538 - -Bug Details: -PixieFail Bug #4 -CVE-2023-45232 -CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H -CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') - -Infinite loop when parsing unknown options in the Destination Options -header - -PixieFail Bug #5 -CVE-2023-45233 -CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H -CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') - -Infinite loop when parsing a PadN option in the Destination Options -header - -Change Overview: - -Most importantly this change corrects the following incorrect math -and cleans up the code. - -> // It is a PadN option -> // -> - Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); -> + OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; -> + Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); - -> case Ip6OptionSkip: -> - Offset = (UINT8)(Offset + *(Option + Offset + 1)); -> OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; -> Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); - -Additionally, this change also corrects incorrect math where the calling -function was calculating the HDR EXT optionLen as a uint8 instead of a -uint16 - -> - OptionLen = (UINT8)((*Option + 1) * 8 - 2); -> + OptionLen = IP6_HDR_EXT_LEN (*Option) - -IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN; - -Additionally this check adds additional logic to santize the incoming -data - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/Ip6Dxe/Ip6Nd.h | 35 ++++++++++++++++ - NetworkPkg/Ip6Dxe/Ip6Option.c | 76 ++++++++++++++++++++++++++++++----- - NetworkPkg/Ip6Dxe/Ip6Option.h | 71 ++++++++++++++++++++++++++++++++ - 3 files changed, 171 insertions(+), 11 deletions(-) - -diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h -index 860934a1..7d6577ad 100644 ---- a/NetworkPkg/Ip6Dxe/Ip6Nd.h -+++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h -@@ -56,13 +56,48 @@ VOID - VOID *Context - ); - -+// -+// Per RFC8200 Section 4.2 -+// -+// Two of the currently-defined extension headers -- the Hop-by-Hop -+// Options header and the Destination Options header -- carry a variable -+// number of type-length-value (TLV) encoded "options", of the following -+// format: -+// -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - -+// | Option Type | Opt Data Len | Option Data -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - -+// -+// Option Type 8-bit identifier of the type of option. -+// -+// Opt Data Len 8-bit unsigned integer. Length of the Option -+// Data field of this option, in octets. -+// -+// Option Data Variable-length field. Option-Type-specific -+// data. -+// - typedef struct _IP6_OPTION_HEADER { -+ /// -+ /// identifier of the type of option. -+ /// - UINT8 Type; -+ /// -+ /// Length of the Option Data field of this option, in octets. -+ /// - UINT8 Length; -+ /// -+ /// Option-Type-specific data. -+ /// - } IP6_OPTION_HEADER; - - STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) == 2, "IP6_OPTION_HEADER is expected to be exactly 2 bytes long."); - -+#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + sizeof(IP6_OPTION_HEADER) + length) -+STATIC_ASSERT ( -+ IP6_NEXT_OPTION_OFFSET (0, 0) == 2, -+ "The next option is minimally the combined size of the option tag and length" -+ ); -+ - typedef struct _IP6_ETHE_ADDR_OPTION { - UINT8 Type; - UINT8 Length; -diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c -index 780771f2..a00c31fc 100644 ---- a/NetworkPkg/Ip6Dxe/Ip6Option.c -+++ b/NetworkPkg/Ip6Dxe/Ip6Option.c -@@ -17,7 +17,8 @@ - @param[in] IpSb The IP6 service data. - @param[in] Packet The to be validated packet. - @param[in] Option The first byte of the option. -- @param[in] OptionLen The length of the whole option. -+ @param[in] OptionLen The length of all options, expressed in byte length of octets. -+ Maximum length is 2046 bytes or ((n + 1) * 8) - 2 where n is 255. - @param[in] Pointer Identifies the octet offset within - the invoking packet where the error was detected. - -@@ -31,12 +32,33 @@ Ip6IsOptionValid ( - IN IP6_SERVICE *IpSb, - IN NET_BUF *Packet, - IN UINT8 *Option, -- IN UINT8 OptionLen, -+ IN UINT16 OptionLen, - IN UINT32 Pointer - ) - { -- UINT8 Offset; -- UINT8 OptionType; -+ UINT16 Offset; -+ UINT8 OptionType; -+ UINT8 OptDataLen; -+ -+ if (Option == NULL) { -+ ASSERT (Option != NULL); -+ return FALSE; -+ } -+ -+ if ((OptionLen <= 0) || (OptionLen > IP6_MAX_EXT_DATA_LENGTH)) { -+ ASSERT (OptionLen > 0 && OptionLen <= IP6_MAX_EXT_DATA_LENGTH); -+ return FALSE; -+ } -+ -+ if (Packet == NULL) { -+ ASSERT (Packet != NULL); -+ return FALSE; -+ } -+ -+ if (IpSb == NULL) { -+ ASSERT (IpSb != NULL); -+ return FALSE; -+ } - - Offset = 0; - -@@ -54,7 +76,8 @@ Ip6IsOptionValid ( - // - // It is a PadN option - // -- Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); -+ OptDataLen = ((IP6_OPTION_HEADER *)(Option + Offset))->Length; -+ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); - break; - case Ip6OptionRouterAlert: - // -@@ -69,7 +92,8 @@ Ip6IsOptionValid ( - // - switch (OptionType & Ip6OptionMask) { - case Ip6OptionSkip: -- Offset = (UINT8)(Offset + *(Option + Offset + 1)); -+ OptDataLen = ((IP6_OPTION_HEADER *)(Option + Offset))->Length; -+ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); - break; - case Ip6OptionDiscard: - return FALSE; -@@ -308,7 +332,7 @@ Ip6IsExtsValid ( - UINT32 Pointer; - UINT32 Offset; - UINT8 *Option; -- UINT8 OptionLen; -+ UINT16 OptionLen; - BOOLEAN Flag; - UINT8 CountD; - UINT8 CountA; -@@ -385,6 +409,36 @@ Ip6IsExtsValid ( - // Fall through - // - case IP6_DESTINATION: -+ // -+ // See https://www.rfc-editor.org/rfc/rfc2460#section-4.2 page 23 -+ // -+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ // | Next Header | Hdr Ext Len | | -+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + -+ // | | -+ // . . -+ // . Options . -+ // . . -+ // | | -+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ // -+ // -+ // Next Header 8-bit selector. Identifies the type of header -+ // immediately following the Destination Options -+ // header. Uses the same values as the IPv4 -+ // Protocol field [RFC-1700 et seq.]. -+ // -+ // Hdr Ext Len 8-bit unsigned integer. Length of the -+ // Destination Options header in 8-octet units, not -+ // including the first 8 octets. -+ // -+ // Options Variable-length field, of length such that the -+ // complete Destination Options header is an -+ // integer multiple of 8 octets long. Contains one -+ // or more TLV-encoded options, as described in -+ // section 4.2. -+ // -+ - if (*NextHeader == IP6_DESTINATION) { - CountD++; - } -@@ -398,7 +452,7 @@ Ip6IsExtsValid ( - - Offset++; - Option = ExtHdrs + Offset; -- OptionLen = (UINT8)((*Option + 1) * 8 - 2); -+ OptionLen = IP6_HDR_EXT_LEN (*Option) - sizeof (IP6_EXT_HDR); - Option++; - Offset++; - -@@ -430,7 +484,7 @@ Ip6IsExtsValid ( - // - // Ignore the routing header and proceed to process the next header. - // -- Offset = Offset + (RoutingHead->HeaderLen + 1) * 8; -+ Offset = Offset + IP6_HDR_EXT_LEN (RoutingHead->HeaderLen); - - if (UnFragmentLen != NULL) { - *UnFragmentLen = Offset; -@@ -441,7 +495,7 @@ Ip6IsExtsValid ( - // to the packet's source address, pointing to the unrecognized routing - // type. - // -- Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER); -+ Pointer = Offset + sizeof (IP6_EXT_HDR) + sizeof (EFI_IP6_HEADER); - if ((IpSb != NULL) && (Packet != NULL) && - !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) - { -@@ -527,7 +581,7 @@ Ip6IsExtsValid ( - // - // RFC2402, Payload length is specified in 32-bit words, minus "2". - // -- OptionLen = (UINT8)((*Option + 2) * 4); -+ OptionLen = ((UINT16)(*Option + 2) * 4); - Offset = Offset + OptionLen; - break; - -diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h -index bd8e223c..ff5f3459 100644 ---- a/NetworkPkg/Ip6Dxe/Ip6Option.h -+++ b/NetworkPkg/Ip6Dxe/Ip6Option.h -@@ -12,6 +12,77 @@ - - #define IP6_FRAGMENT_OFFSET_MASK (~0x3) - -+// -+// For more information see RFC 8200, Section 4.3, 4.4, and 4.6 -+// -+// This example format is from section 4.6 -+// This does not apply to fragment headers -+// -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// | Next Header | Hdr Ext Len | | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + -+// | | -+// . . -+// . Header-Specific Data . -+// . . -+// | | -+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+// -+// Next Header 8-bit selector. Identifies the type of -+// header immediately following the extension -+// header. Uses the same values as the IPv4 -+// Protocol field [IANA-PN]. -+// -+// Hdr Ext Len 8-bit unsigned integer. Length of the -+// Destination Options header in 8-octet units, -+// not including the first 8 octets. -+ -+// -+// These defines apply to the following: -+// 1. Hop by Hop -+// 2. Routing -+// 3. Destination -+// -+typedef struct _IP6_EXT_HDR { -+ /// -+ /// The Next Header field identifies the type of header immediately -+ /// -+ UINT8 NextHeader; -+ /// -+ /// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options -+ /// -+ UINT8 HdrExtLen; -+ /// -+ /// Header-Specific Data -+ /// -+} IP6_EXT_HDR; -+ -+STATIC_ASSERT ( -+ sizeof (IP6_EXT_HDR) == 2, -+ "The combined size of Next Header and Len is two 8 bit fields" -+ ); -+ -+// -+// IPv6 extension headers contain an 8-bit length field which describes the size of -+// the header. However, the length field only includes the size of the extension -+// header options, not the size of the first 8 bytes of the header. Therefore, in -+// order to calculate the full size of the extension header, we add 1 (to account -+// for the first 8 bytes omitted by the length field reporting) and then multiply -+// by 8 (since the size is represented in 8-byte units). -+// -+// a is the length field of the extension header (UINT8) -+// The result may be up to 2046 octets (UINT16) -+// -+#define IP6_HDR_EXT_LEN(a) (((UINT16)((UINT8)(a)) + 1) * 8) -+ -+// This is the maxmimum length permissible by a extension header -+// Length is UINT8 of 8 octets not including the first 8 octets -+#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - sizeof(IP6_EXT_HDR)) -+STATIC_ASSERT ( -+ IP6_MAX_EXT_DATA_LENGTH == 2046, -+ "Maximum data length is ((MAX_UINT8 + 1) * 8) - 2" -+ ); -+ - typedef struct _IP6_FRAGMENT_HEADER { - UINT8 NextHeader; - UINT8 Reserved; --- -2.33.0 - diff --git a/0029-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch b/0029-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch deleted file mode 100644 index 6511a3dfd36d074455452248364591d24d40134d..0000000000000000000000000000000000000000 --- a/0029-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch +++ /dev/null @@ -1,415 +0,0 @@ -From fdc3bfda40e74eb0fe19b387f7d0dd6199b06e85 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:51 +0800 -Subject: [PATCH 09/19] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit - Tests - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537 -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538 - -Unit tests to confirm that.. - -Infinite loop when parsing unknown options in the Destination Options -header - -and - -Infinite loop when parsing a PadN option in the Destination Options -header - -... have been patched - -This patch tests the following functions: -Ip6IsOptionValid - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 10 +- - .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 278 ++++++++++++++++++ - .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h | 40 +++ - 3 files changed, 324 insertions(+), 4 deletions(-) - create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h - -diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf -index 60396b05..489a45f1 100644 ---- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf -+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf -@@ -1,13 +1,13 @@ - ## @file --# Unit test suite for the Ip6Dxe using Google Test -+# Unit test suite for the Ip6DxeGoogleTest using Google Test - # - # Copyright (c) Microsoft Corporation.
- # SPDX-License-Identifier: BSD-2-Clause-Patent - ## - [Defines] - INF_VERSION = 0x00010017 -- BASE_NAME = Ip6DxeUnitTest -- FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A -+ BASE_NAME = Ip6DxeGoogleTest -+ FILE_GUID = AE39981C-B7FE-41A8-A9C2-F41910477CA3 - VERSION_STRING = 1.0 - MODULE_TYPE = HOST_APPLICATION - # -@@ -16,9 +16,11 @@ - # VALID_ARCHITECTURES = IA32 X64 AARCH64 - # - [Sources] -+ ../Ip6Option.c -+ Ip6OptionGoogleTest.h - Ip6DxeGoogleTest.cpp - Ip6OptionGoogleTest.cpp -- ../Ip6Option.c -+ Ip6OptionGoogleTest.h - - [Packages] - MdePkg/MdePkg.dec -diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp -index 874400eb..c12cbc0d 100644 ---- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp -+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp -@@ -12,6 +12,7 @@ extern "C" { - #include - #include "../Ip6Impl.h" - #include "../Ip6Option.h" -+ #include "Ip6OptionGoogleTest.h" - } - - ///////////////////////////////////////////////////////////////////////// -@@ -127,3 +128,280 @@ TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse) - - EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); - } -+ -+//////////////////////////////////////////////////////////////////////// -+// Ip6IsOptionValid Tests -+//////////////////////////////////////////////////////////////////////// -+ -+// Define a fixture for your tests if needed -+class Ip6IsOptionValidTest : public ::testing::Test { -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ // Initialize any resources or variables -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ // Clean up any resources or variables -+ } -+}; -+ -+// Test Description -+// Verify that a NULL option is Invalid -+TEST_F (Ip6IsOptionValidTest, NullOptionShouldReturnTrue) { -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ IP6_SERVICE *IpSb = NULL; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ EXPECT_FALSE (Ip6IsOptionValid (IpSb, &Packet, NULL, 0, 0)); -+} -+ -+// Test Description -+// Verify that an unknown option with a length of 0 and type of does not cause an infinite loop -+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength0) { -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ UINT32 DeadCode = 0xDeadC0de; -+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it -+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = 23; // Unknown Option -+ optionHeader.Length = 0; // This will cause an infinite loop if the function is not working correctly -+ -+ // This should be a valid option even though the length is 0 -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+} -+ -+// Test Description -+// Verify that an unknown option with a length of 1 and type of does not cause an infinite loop -+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength1) { -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ UINT32 DeadCode = 0xDeadC0de; -+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it -+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = 23; // Unknown Option -+ optionHeader.Length = 1; // This will cause an infinite loop if the function is not working correctly -+ -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+} -+ -+// Test Description -+// Verify that an unknown option with a length of 2 and type of does not cause an infinite loop -+TEST_F (Ip6IsOptionValidTest, VerifyIpSkipUnknownOption) { -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ UINT32 DeadCode = 0xDeadC0de; -+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it -+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = 23; // Unknown Option -+ optionHeader.Length = 2; // Valid length for an unknown option -+ -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+} -+ -+// Test Description -+// Verify that Ip6OptionPad1 is valid with a length of 0 -+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPad1) { -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ UINT32 DeadCode = 0xDeadC0de; -+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it -+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = Ip6OptionPad1; -+ optionHeader.Length = 0; -+ -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+} -+ -+// Test Description -+// Verify that Ip6OptionPadN doesn't overflow with various lengths -+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPadN) { -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ UINT32 DeadCode = 0xDeadC0de; -+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it -+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = Ip6OptionPadN; -+ optionHeader.Length = 0xFF; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+ -+ optionHeader.Length = 0xFE; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+ -+ optionHeader.Length = 0xFD; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+ -+ optionHeader.Length = 0xFC; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+} -+ -+// Test Description -+// Verify an unknown option doesn't cause an infinite loop with various lengths -+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLengthAttemptOverflow) { -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ UINT32 DeadCode = 0xDeadC0de; -+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it -+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ IP6_OPTION_HEADER optionHeader; -+ -+ optionHeader.Type = 23; // Unknown Option -+ optionHeader.Length = 0xFF; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+ -+ optionHeader.Length = 0xFE; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+ -+ optionHeader.Length = 0xFD; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+ -+ optionHeader.Length = 0xFC; -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); -+} -+ -+// Test Description -+// Verify that the function supports multiple options -+TEST_F (Ip6IsOptionValidTest, MultiOptionSupport) { -+ UINT16 HdrLen; -+ NET_BUF Packet = { 0 }; -+ // we need to define enough of the packet to make the function work -+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above -+ UINT32 DeadCode = 0xDeadC0de; -+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it -+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; -+ -+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; -+ EFI_IP6_HEADER Ip6Header = { 0 }; -+ -+ Ip6Header.SourceAddress = SourceAddress; -+ Ip6Header.DestinationAddress = DestinationAddress; -+ Packet.Ip.Ip6 = &Ip6Header; -+ -+ UINT8 ExtHdr[1024] = { 0 }; -+ UINT8 *Cursor = ExtHdr; -+ IP6_OPTION_HEADER *Option = (IP6_OPTION_HEADER *)ExtHdr; -+ -+ // Let's start chaining options -+ -+ Option->Type = 23; // Unknown Option -+ Option->Length = 0xFC; -+ -+ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC; -+ -+ Option = (IP6_OPTION_HEADER *)Cursor; -+ Option->Type = Ip6OptionPad1; -+ -+ Cursor += sizeof (1); -+ -+ // Type and length aren't processed, instead it just moves the pointer forward by 4 bytes -+ Option = (IP6_OPTION_HEADER *)Cursor; -+ Option->Type = Ip6OptionRouterAlert; -+ Option->Length = 4; -+ -+ Cursor += sizeof (IP6_OPTION_HEADER) + 4; -+ -+ Option = (IP6_OPTION_HEADER *)Cursor; -+ Option->Type = Ip6OptionPadN; -+ Option->Length = 0xFC; -+ -+ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC; -+ -+ Option = (IP6_OPTION_HEADER *)Cursor; -+ Option->Type = Ip6OptionRouterAlert; -+ Option->Length = 4; -+ -+ Cursor += sizeof (IP6_OPTION_HEADER) + 4; -+ -+ // Total 524 -+ -+ HdrLen = (UINT16)(Cursor - ExtHdr); -+ -+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, ExtHdr, HdrLen, 0)); -+} -diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h -new file mode 100644 -index 00000000..af61f608 ---- /dev/null -+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h -@@ -0,0 +1,40 @@ -+/** @file -+ Exposes the functions needed to test the Ip6Option module. -+ -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+ -+#ifndef IP6_OPTION_HEADER_GOOGLE_TEST_H_ -+#define IP6_OPTION_HEADER_GOOGLE_TEST_H_ -+ -+#include -+#include "../Ip6Impl.h" -+ -+/** -+ Validate the IP6 option format for both the packets we received -+ and that we will transmit. It will compute the ICMPv6 error message fields -+ if the option is malformatted. -+ -+ @param[in] IpSb The IP6 service data. -+ @param[in] Packet The to be validated packet. -+ @param[in] Option The first byte of the option. -+ @param[in] OptionLen The length of the whole option. -+ @param[in] Pointer Identifies the octet offset within -+ the invoking packet where the error was detected. -+ -+ -+ @retval TRUE The option is properly formatted. -+ @retval FALSE The option is malformatted. -+ -+**/ -+BOOLEAN -+Ip6IsOptionValid ( -+ IN IP6_SERVICE *IpSb, -+ IN NET_BUF *Packet, -+ IN UINT8 *Option, -+ IN UINT16 OptionLen, -+ IN UINT32 Pointer -+ ); -+ -+#endif // __IP6_OPTION_HEADER_GOOGLE_TEST_H__ --- -2.33.0 - diff --git a/0030-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0030-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch deleted file mode 100644 index 55317e42fe018973bcbaea35383287edf0606b75..0000000000000000000000000000000000000000 --- a/0030-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 2805c504f0bb95a9cb2ff4e36cfe5b918ab23c0d Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:52 +0800 -Subject: [PATCH 10/19] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 - Patch - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539 - -Bug Details: -PixieFail Bug #6 -CVE-2023-45234 -CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H -CWE-119 Improper Restriction of Operations within the Bounds of - a Memory Buffer - -Buffer overflow when processing DNS Servers option in a DHCPv6 -Advertise message - -Change Overview: - -Introduces a function to cache the Dns Server and perform sanitizing -on the incoming DnsServerLen to ensure that the length is valid - -> + EFI_STATUS -> + PxeBcCacheDnsServerAddresses ( -> + IN PXEBC_PRIVATE_DATA *Private, -> + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 -> + ) - -Additional code cleanup - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 71 +++++++++++++++++++++++++--- - 1 file changed, 65 insertions(+), 6 deletions(-) - -diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -index 425e0cf8..e984b928 100644 ---- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -@@ -3,6 +3,7 @@ - - (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
-+ Copyright (c) Microsoft Corporation - - SPDX-License-Identifier: BSD-2-Clause-Patent - -@@ -1312,6 +1313,65 @@ PxeBcSelectDhcp6Offer ( - } - } - -+/** -+ Cache the DHCPv6 DNS Server addresses -+ -+ @param[in] Private The pointer to PXEBC_PRIVATE_DATA. -+ @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE. -+ -+ @retval EFI_SUCCESS Cache the DHCPv6 DNS Server address successfully. -+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. -+ @retval EFI_DEVICE_ERROR The DNS Server Address Length provided by a untrusted -+ option is not a multiple of 16 bytes (sizeof (EFI_IPv6_ADDRESS)). -+**/ -+EFI_STATUS -+PxeBcCacheDnsServerAddresses ( -+ IN PXEBC_PRIVATE_DATA *Private, -+ IN PXEBC_DHCP6_PACKET_CACHE *Cache6 -+ ) -+{ -+ UINT16 DnsServerLen; -+ -+ DnsServerLen = NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen); -+ // -+ // Make sure that the number is nonzero -+ // -+ if (DnsServerLen == 0) { -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // Make sure the DnsServerlen is a multiple of EFI_IPv6_ADDRESS (16) -+ // -+ if (DnsServerLen % sizeof (EFI_IPv6_ADDRESS) != 0) { -+ return EFI_DEVICE_ERROR; -+ } -+ -+ // -+ // This code is currently written to only support a single DNS Server instead -+ // of multiple such as is spec defined (RFC3646, Section 3). The proper behavior -+ // would be to allocate the full space requested, CopyMem all of the data, -+ // and then add a DnsServerCount field to Private and update additional code -+ // that depends on this. -+ // -+ // To support multiple DNS servers the `AllocationSize` would need to be changed to DnsServerLen -+ // -+ // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886 -+ // -+ Private->DnsServer = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS)); -+ if (Private->DnsServer == NULL) { -+ return EFI_OUT_OF_RESOURCES; -+ } -+ -+ // -+ // Intentionally only copy over the first server address. -+ // To support multiple DNS servers, the `Length` would need to be changed to DnsServerLen -+ // -+ CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS)); -+ -+ return EFI_SUCCESS; -+} -+ - /** - Handle the DHCPv6 offer packet. - -@@ -1335,6 +1395,7 @@ PxeBcHandleDhcp6Offer ( - UINT32 SelectIndex; - UINT32 Index; - -+ ASSERT (Private != NULL); - ASSERT (Private->SelectIndex > 0); - SelectIndex = (UINT32)(Private->SelectIndex - 1); - ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM); -@@ -1342,15 +1403,13 @@ PxeBcHandleDhcp6Offer ( - Status = EFI_SUCCESS; - - // -- // First try to cache DNS server address if DHCP6 offer provides. -+ // First try to cache DNS server addresses if DHCP6 offer provides. - // - if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] != NULL) { -- Private->DnsServer = AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen)); -- if (Private->DnsServer == NULL) { -- return EFI_OUT_OF_RESOURCES; -+ Status = PxeBcCacheDnsServerAddresses (Private, Cache6); -+ if (EFI_ERROR (Status)) { -+ return Status; - } -- -- CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS)); - } - - if (Cache6->OfferType == PxeOfferTypeDhcpBinl) { --- -2.33.0 - diff --git a/0031-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0031-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch deleted file mode 100644 index 32ac86e020056fc1923d204138d56af851a355df..0000000000000000000000000000000000000000 --- a/0031-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +++ /dev/null @@ -1,495 +0,0 @@ -From e10aa0978745e9e46b1cf67158b5582ab0317d82 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:53 +0800 -Subject: [PATCH 11/19] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 - Unit Tests - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539 - -Unit tests to that the bug.. - -Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise -message - -..has been patched - -This contains tests for the following functions: -PxeBcHandleDhcp6Offer -PxeBcCacheDnsServerAddresses - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + - .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 300 ++++++++++++++++++ - .../GoogleTest/PxeBcDhcp6GoogleTest.h | 50 +++ - .../GoogleTest/UefiPxeBcDxeGoogleTest.cpp | 19 ++ - .../GoogleTest/UefiPxeBcDxeGoogleTest.inf | 48 +++ - 5 files changed, 418 insertions(+) - create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp - create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h - create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp - create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf - -diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc -index b4ea0a77..e26a2598 100644 ---- a/NetworkPkg/Test/NetworkPkgHostTest.dsc -+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc -@@ -27,6 +27,7 @@ - # - NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf - NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf -+ NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf - - # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. - [LibraryClasses] -diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp -new file mode 100644 -index 00000000..c66a60bc ---- /dev/null -+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp -@@ -0,0 +1,300 @@ -+/** @file -+ Host based unit test for PxeBcDhcp6.c. -+ -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+ -+extern "C" { -+ #include -+ #include -+ #include -+ #include "../PxeBcImpl.h" -+ #include "../PxeBcDhcp6.h" -+ #include "PxeBcDhcp6GoogleTest.h" -+} -+ -+/////////////////////////////////////////////////////////////////////////////// -+// Definitions -+/////////////////////////////////////////////////////////////////////////////// -+ -+#define PACKET_SIZE (1500) -+ -+typedef struct { -+ UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03) -+ UINT16 OptionLen; // The length of the option (e.g., 16 bytes) -+ UINT8 ServerId[16]; // The 16-byte DHCPv6 Server Identifier -+} DHCP6_OPTION_SERVER_ID; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/// Symbol Definitions -+/////////////////////////////////////////////////////////////////////////////// -+ -+EFI_STATUS -+MockUdpWrite ( -+ IN EFI_PXE_BASE_CODE_PROTOCOL *This, -+ IN UINT16 OpFlags, -+ IN EFI_IP_ADDRESS *DestIp, -+ IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, -+ IN EFI_IP_ADDRESS *GatewayIp OPTIONAL, -+ IN EFI_IP_ADDRESS *SrcIp OPTIONAL, -+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, -+ IN UINTN *HeaderSize OPTIONAL, -+ IN VOID *HeaderPtr OPTIONAL, -+ IN UINTN *BufferSize, -+ IN VOID *BufferPtr -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ -+EFI_STATUS -+MockUdpRead ( -+ IN EFI_PXE_BASE_CODE_PROTOCOL *This, -+ IN UINT16 OpFlags, -+ IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL, -+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL, -+ IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL, -+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, -+ IN UINTN *HeaderSize OPTIONAL, -+ IN VOID *HeaderPtr OPTIONAL, -+ IN OUT UINTN *BufferSize, -+ IN VOID *BufferPtr -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ -+EFI_STATUS -+MockConfigure ( -+ IN EFI_UDP6_PROTOCOL *This, -+ IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ -+// Needed by PxeBcSupport -+EFI_STATUS -+EFIAPI -+QueueDpc ( -+ IN EFI_TPL DpcTpl, -+ IN EFI_DPC_PROCEDURE DpcProcedure, -+ IN VOID *DpcContext OPTIONAL -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ -+/////////////////////////////////////////////////////////////////////////////// -+// PxeBcHandleDhcp6OfferTest Tests -+/////////////////////////////////////////////////////////////////////////////// -+ -+class PxeBcHandleDhcp6OfferTest : public ::testing::Test { -+public: -+ PXEBC_PRIVATE_DATA Private = { 0 }; -+ EFI_UDP6_PROTOCOL Udp6Read; -+ EFI_PXE_BASE_CODE_MODE Mode = { 0 }; -+ -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); -+ -+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL -+ // The function under test really only needs the following: -+ // UdpWrite -+ // UdpRead -+ -+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; -+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; -+ -+ // Need to setup EFI_UDP6_PROTOCOL -+ // The function under test really only needs the following: -+ // Configure -+ -+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure; -+ Private.Udp6Read = &Udp6Read; -+ -+ // Need to setup the EFI_PXE_BASE_CODE_MODE -+ Private.PxeBc.Mode = &Mode; -+ -+ // for this test it doesn't really matter what the Dhcpv6 ack is set to -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ if (Private.Dhcp6Request != NULL) { -+ FreePool (Private.Dhcp6Request); -+ } -+ -+ // Clean up any resources or variables -+ } -+}; -+ -+// Note: -+// Testing PxeBcHandleDhcp6Offer() is difficult because it depends on a -+// properly setup Private structure. Attempting to properly test this function -+// without a signficant refactor is a fools errand. Instead, we will test -+// that we can prevent an overflow in the function. -+TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) { -+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; -+ EFI_DHCP6_PACKET_OPTION Option = { 0 }; -+ -+ Private.SelectIndex = 1; // SelectIndex is 1-based -+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; -+ -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; -+ // Setup the DHCPv6 offer packet -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (1337); -+ -+ ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR); -+} -+ -+class PxeBcCacheDnsServerAddressesTest : public ::testing::Test { -+public: -+ PXEBC_PRIVATE_DATA Private = { 0 }; -+ -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ } -+}; -+ -+// Test Description -+// Test that we cache the DNS server address from the DHCPv6 offer packet -+TEST_F (PxeBcCacheDnsServerAddressesTest, BasicUsageTest) { -+ UINT8 SearchPattern[16] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF }; -+ EFI_DHCP6_PACKET_OPTION *Option; -+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; -+ -+ Option = (EFI_DHCP6_PACKET_OPTION *)AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + sizeof (SearchPattern)); -+ ASSERT_NE (Option, nullptr); -+ -+ Option->OpCode = DHCP6_OPT_SERVER_ID; -+ Option->OpLen = NTOHS (sizeof (SearchPattern)); -+ CopyMem (Option->Data, SearchPattern, sizeof (SearchPattern)); -+ -+ Private.SelectIndex = 1; // SelectIndex is 1-based -+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option; -+ -+ Private.DnsServer = nullptr; -+ -+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS); -+ ASSERT_NE (Private.DnsServer, nullptr); -+ ASSERT_EQ (CompareMem (Private.DnsServer, SearchPattern, sizeof (SearchPattern)), 0); -+ -+ if (Private.DnsServer) { -+ FreePool (Private.DnsServer); -+ } -+ -+ if (Option) { -+ FreePool (Option); -+ } -+} -+// Test Description -+// Test that we can prevent an overflow in the function -+TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptOverflowTest) { -+ EFI_DHCP6_PACKET_OPTION Option = { 0 }; -+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; -+ -+ Private.SelectIndex = 1; // SelectIndex is 1-based -+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; -+ // Setup the DHCPv6 offer packet -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (1337); -+ -+ Private.DnsServer = NULL; -+ -+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR); -+ ASSERT_EQ (Private.DnsServer, nullptr); -+ -+ if (Private.DnsServer) { -+ FreePool (Private.DnsServer); -+ } -+} -+ -+// Test Description -+// Test that we can prevent an underflow in the function -+TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) { -+ EFI_DHCP6_PACKET_OPTION Option = { 0 }; -+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; -+ -+ Private.SelectIndex = 1; // SelectIndex is 1-based -+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; -+ // Setup the DHCPv6 offer packet -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (2); -+ -+ Private.DnsServer = NULL; -+ -+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR); -+ ASSERT_EQ (Private.DnsServer, nullptr); -+ -+ if (Private.DnsServer) { -+ FreePool (Private.DnsServer); -+ } -+} -+ -+// Test Description -+// Test that we can handle recursive dns (multiple dns entries) -+TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { -+ EFI_DHCP6_PACKET_OPTION Option = { 0 }; -+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; -+ -+ Private.SelectIndex = 1; // SelectIndex is 1-based -+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; -+ // Setup the DHCPv6 offer packet -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; -+ -+ EFI_IPv6_ADDRESS addresses[2] = { -+ // 2001:db8:85a3::8a2e:370:7334 -+ { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }, -+ // fe80::d478:91c3:ecd7:4ff9 -+ { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 } -+ }; -+ -+ CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses)); -+ -+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses)); -+ -+ Private.DnsServer = NULL; -+ -+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS); -+ -+ ASSERT_NE (Private.DnsServer, nullptr); -+ -+ // -+ // This is expected to fail until DnsServer supports multiple DNS servers -+ // -+ // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886 -+ // -+ // Disabling: -+ // ASSERT_EQ (CompareMem(Private.DnsServer, &addresses, sizeof(addresses)), 0); -+ -+ if (Private.DnsServer) { -+ FreePool (Private.DnsServer); -+ } -+} -diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h -new file mode 100644 -index 00000000..48ab238d ---- /dev/null -+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h -@@ -0,0 +1,50 @@ -+/** @file -+ This file exposes the internal interfaces which may be unit tested -+ for the PxeBcDhcp6Dxe driver. -+ -+ Copyright (c) Microsoft Corporation.
-+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+ -+#ifndef PXE_BC_DHCP6_GOOGLE_TEST_H_ -+#define PXE_BC_DHCP6_GOOGLE_TEST_H_ -+ -+// -+// Minimal includes needed to compile -+// -+#include -+#include "../PxeBcImpl.h" -+ -+/** -+ Handle the DHCPv6 offer packet. -+ -+ @param[in] Private The pointer to PXEBC_PRIVATE_DATA. -+ -+ @retval EFI_SUCCESS Handled the DHCPv6 offer packet successfully. -+ @retval EFI_NO_RESPONSE No response to the following request packet. -+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. -+ @retval EFI_BUFFER_TOO_SMALL Can't cache the offer pacet. -+ -+**/ -+EFI_STATUS -+PxeBcHandleDhcp6Offer ( -+ IN PXEBC_PRIVATE_DATA *Private -+ ); -+ -+/** -+ Cache the DHCPv6 Server address -+ -+ @param[in] Private The pointer to PXEBC_PRIVATE_DATA. -+ @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE. -+ -+ @retval EFI_SUCCESS Cache the DHCPv6 Server address successfully. -+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. -+ @retval EFI_DEVICE_ERROR Failed to cache the DHCPv6 Server address. -+**/ -+EFI_STATUS -+PxeBcCacheDnsServerAddresses ( -+ IN PXEBC_PRIVATE_DATA *Private, -+ IN PXEBC_DHCP6_PACKET_CACHE *Cache6 -+ ); -+ -+#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_ -diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp -new file mode 100644 -index 00000000..ff159e45 ---- /dev/null -+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp -@@ -0,0 +1,19 @@ -+/** @file -+ Acts as the main entry point for the tests for the UefiPxeBcDxe module. -+ Copyright (c) Microsoft Corporation -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+**/ -+#include -+ -+//////////////////////////////////////////////////////////////////////////////// -+// Run the tests -+//////////////////////////////////////////////////////////////////////////////// -+int -+main ( -+ int argc, -+ char *argv[] -+ ) -+{ -+ testing::InitGoogleTest (&argc, argv); -+ return RUN_ALL_TESTS (); -+} -diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf -new file mode 100644 -index 00000000..0097142b ---- /dev/null -+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf -@@ -0,0 +1,48 @@ -+## @file -+# Unit test suite for the UefiPxeBcDxe using Google Test -+# -+# Copyright (c) Microsoft Corporation.
-+# SPDX-License-Identifier: BSD-2-Clause-Patent -+## -+[Defines] -+INF_VERSION = 0x00010005 -+BASE_NAME = UefiPxeBcDxeGoogleTest -+FILE_GUID = 77D45C64-EC1E-4174-887B-886E89FD1EDF -+MODULE_TYPE = HOST_APPLICATION -+VERSION_STRING = 1.0 -+ -+# -+# The following information is for reference only and not required by the build tools. -+# -+# VALID_ARCHITECTURES = IA32 X64 -+# -+ -+[Sources] -+ UefiPxeBcDxeGoogleTest.cpp -+ PxeBcDhcp6GoogleTest.cpp -+ PxeBcDhcp6GoogleTest.h -+ ../PxeBcDhcp6.c -+ ../PxeBcSupport.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ MdeModulePkg/MdeModulePkg.dec -+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec -+ NetworkPkg/NetworkPkg.dec -+ -+[LibraryClasses] -+ GoogleTestLib -+ DebugLib -+ NetLib -+ PcdLib -+ -+[Protocols] -+ gEfiDhcp6ServiceBindingProtocolGuid -+ gEfiDns6ServiceBindingProtocolGuid -+ gEfiDns6ProtocolGuid -+ -+[Pcd] -+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType -+ -+[Guids] -+ gZeroGuid --- -2.33.0 - diff --git a/0032-MdePkg-Test-Add-gRT_GetTime-Google-Test-Mock.patch b/0032-MdePkg-Test-Add-gRT_GetTime-Google-Test-Mock.patch deleted file mode 100644 index cca90a53b4490471258a0caa168e37f70f2cc5a4..0000000000000000000000000000000000000000 --- a/0032-MdePkg-Test-Add-gRT_GetTime-Google-Test-Mock.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7da4834de41ef7e9621d022546ac277fd24690f1 Mon Sep 17 00:00:00 2001 -From: "Doug Flick via groups.io" -Date: Fri, 26 Jan 2024 05:54:54 +0800 -Subject: [PATCH 12/19] MdePkg: Test: Add gRT_GetTime Google Test Mock - -This adds support for GetTime Google Test Mock - -Cc: Michael D Kinney -Cc: Liming Gao -Cc: Zhiguang Liu - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Michael D Kinney - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - .../GoogleTest/Library/MockUefiRuntimeServicesTableLib.h | 7 +++++++ - .../MockUefiRuntimeServicesTableLib.cpp | 3 ++- - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h -index afdfc6b8..57ec889e 100644 ---- a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h -+++ b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h -@@ -37,6 +37,13 @@ struct MockUefiRuntimeServicesTableLib { - IN UINTN DataSize, - IN VOID *Data) - ); -+ -+ MOCK_FUNCTION_DECLARATION ( -+ EFI_STATUS, -+ gRT_GetTime, -+ (OUT EFI_TIME *Time, -+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL) -+ ); - }; - - #endif -diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp -index ecd1ba82..06121fc5 100644 ---- a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp -+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp -@@ -10,11 +10,12 @@ MOCK_INTERFACE_DEFINITION(MockUefiRuntimeServicesTableLib); - - MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_GetVariable, 5, EFIAPI); - MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_SetVariable, 5, EFIAPI); -+MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_GetTime, 2, EFIAPI); - - static EFI_RUNTIME_SERVICES localRt = { - {0}, // EFI_TABLE_HEADER - -- NULL, // EFI_GET_TIME -+ gRT_GetTime, // EFI_GET_TIME - NULL, // EFI_SET_TIME - NULL, // EFI_GET_WAKEUP_TIME - NULL, // EFI_SET_WAKEUP_TIME --- -2.33.0 - diff --git a/0033-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0033-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch deleted file mode 100644 index e81523fc17c8afc20fa82f181bd7ad631e720bd8..0000000000000000000000000000000000000000 --- a/0033-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +++ /dev/null @@ -1,241 +0,0 @@ -From f0044c58c0ad5c093fe0eb6000b74c1af8d62c23 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:55 +0800 -Subject: [PATCH 13/19] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 - Patch - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540 - -Bug Details: -PixieFail Bug #7 -CVE-2023-45235 -CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H -CWE-119 Improper Restriction of Operations within the Bounds of - a Memory Buffer - -Buffer overflow when handling Server ID option from a DHCPv6 proxy -Advertise message - -Change Overview: - -Performs two checks - -1. Checks that the length of the duid is accurate -> + // -> + // Check that the minimum and maximum requirements are met -> + // -> + if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || -(OpLen > PXEBC_MAX_SIZE_OF_DUID)) { -> + Status = EFI_INVALID_PARAMETER; -> + goto ON_ERROR; -> + } - -2. Ensures that the amount of data written to the buffer is tracked and -never exceeds that -> + // -> + // Check that the option length is valid. -> + // -> + if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) - > DiscoverLenNeeded) { -> + Status = EFI_OUT_OF_RESOURCES; -> + goto ON_ERROR; -> + } - -Additional code clean up and fix for memory leak in case Option was NULL - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 77 ++++++++++++++++++++++------ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 ++++++ - 2 files changed, 78 insertions(+), 16 deletions(-) - -diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -index e984b928..1eb5987c 100644 ---- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -@@ -887,6 +887,7 @@ PxeBcRequestBootService ( - EFI_STATUS Status; - EFI_DHCP6_PACKET *IndexOffer; - UINT8 *Option; -+ UINTN DiscoverLenNeeded; - - PxeBc = &Private->PxeBc; - Request = Private->Dhcp6Request; -@@ -899,7 +900,8 @@ PxeBcRequestBootService ( - return EFI_DEVICE_ERROR; - } - -- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); -+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); -+ Discover = AllocateZeroPool (DiscoverLenNeeded); - if (Discover == NULL) { - return EFI_OUT_OF_RESOURCES; - } -@@ -924,16 +926,34 @@ PxeBcRequestBootService ( - DHCP6_OPT_SERVER_ID - ); - if (Option == NULL) { -- return EFI_NOT_FOUND; -+ Status = EFI_NOT_FOUND; -+ goto ON_ERROR; - } - - // - // Add Server ID Option. - // - OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen); -- CopyMem (DiscoverOpt, Option, OpLen + 4); -- DiscoverOpt += (OpLen + 4); -- DiscoverLen += (OpLen + 4); -+ -+ // -+ // Check that the minimum and maximum requirements are met -+ // -+ if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) { -+ Status = EFI_INVALID_PARAMETER; -+ goto ON_ERROR; -+ } -+ -+ // -+ // Check that the option length is valid. -+ // -+ if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) { -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; -+ } -+ -+ CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); - } - - while (RequestLen < Request->Length) { -@@ -944,16 +964,24 @@ PxeBcRequestBootService ( - (OpCode != DHCP6_OPT_SERVER_ID) - ) - { -+ // -+ // Check that the option length is valid. -+ // -+ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) { -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; -+ } -+ - // - // Copy all the options except IA option and Server ID - // -- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); -- DiscoverOpt += (OpLen + 4); -- DiscoverLen += (OpLen + 4); -+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); - } - -- RequestOpt += (OpLen + 4); -- RequestLen += (OpLen + 4); -+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); - } - - // -@@ -2154,6 +2182,7 @@ PxeBcDhcp6Discover ( - UINT16 OpLen; - UINT32 Xid; - EFI_STATUS Status; -+ UINTN DiscoverLenNeeded; - - PxeBc = &Private->PxeBc; - Mode = PxeBc->Mode; -@@ -2169,7 +2198,8 @@ PxeBcDhcp6Discover ( - return EFI_DEVICE_ERROR; - } - -- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); -+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); -+ Discover = AllocateZeroPool (DiscoverLenNeeded); - if (Discover == NULL) { - return EFI_OUT_OF_RESOURCES; - } -@@ -2185,22 +2215,37 @@ PxeBcDhcp6Discover ( - DiscoverLen = sizeof (EFI_DHCP6_HEADER); - RequestLen = DiscoverLen; - -+ // -+ // The request packet is generated by the UEFI network stack. In the DHCP4 DORA and DHCP6 SARR sequence, -+ // the first (discover in DHCP4 and solicit in DHCP6) and third (request in both DHCP4 and DHCP6) are -+ // generated by the DHCP client (the UEFI network stack in this case). By the time this function executes, -+ // the DHCP sequence already has been executed once (see UEFI Specification Figures 24.2 and 24.3), with -+ // Private->Dhcp6Request being a cached copy of the DHCP6 request packet that UEFI network stack previously -+ // generated and sent. -+ // -+ // Therefore while this code looks like it could overflow, in practice it's not possible. -+ // - while (RequestLen < Request->Length) { - OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpCode); - OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpLen); - if ((OpCode != EFI_DHCP6_IA_TYPE_NA) && - (OpCode != EFI_DHCP6_IA_TYPE_TA)) - { -+ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) { -+ Status = EFI_OUT_OF_RESOURCES; -+ goto ON_ERROR; -+ } -+ - // - // Copy all the options except IA option. - // -- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); -- DiscoverOpt += (OpLen + 4); -- DiscoverLen += (OpLen + 4); -+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); - } - -- RequestOpt += (OpLen + 4); -- RequestLen += (OpLen + 4); -+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); -+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); - } - - Status = PxeBc->UdpWrite ( -diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h -index c86f6d39..3ea0a2fe 100644 ---- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h -+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h -@@ -34,6 +34,23 @@ - #define PXEBC_ADDR_START_DELIMITER '[' - #define PXEBC_ADDR_END_DELIMITER ']' - -+// -+// A DUID consists of a 2-octet type code represented in network byte -+// order, followed by a variable number of octets that make up the -+// actual identifier. The length of the DUID (not including the type -+// code) is at least 1 octet and at most 128 octets. -+// -+#define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1) -+#define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128) -+ -+// -+// This define represents the combineds code and length field from -+// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1 -+// -+#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \ -+ (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \ -+ sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen)) -+ - #define GET_NEXT_DHCP6_OPTION(Opt) \ - (EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \ - sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1) --- -2.33.0 - diff --git a/0034-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0034-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch deleted file mode 100644 index c694810a2129610b05ddd7e61c24e8d19ca09b8a..0000000000000000000000000000000000000000 --- a/0034-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +++ /dev/null @@ -1,393 +0,0 @@ -From 3236b614ee778d5fec0b58098bb5b7b5e88a9bca Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Fri, 26 Jan 2024 05:54:56 +0800 -Subject: [PATCH 14/19] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 - Unit Tests - -REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540 - -Unit tests to confirm that the bug.. - -Buffer overflow when handling Server ID option from a DHCPv6 proxy -Advertise message - -..has been patched. - -This patch contains unit tests for the following functions: -PxeBcRequestBootService -PxeBcDhcp6Discover - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/Test/NetworkPkgHostTest.dsc | 5 +- - .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 278 +++++++++++++++++- - .../GoogleTest/PxeBcDhcp6GoogleTest.h | 18 ++ - 3 files changed, 298 insertions(+), 3 deletions(-) - -diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc -index e26a2598..f313a605 100644 ---- a/NetworkPkg/Test/NetworkPkgHostTest.dsc -+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc -@@ -27,7 +27,10 @@ - # - NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf - NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf -- NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf -+ NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf { -+ -+ UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf -+ } - - # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. - [LibraryClasses] -diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp -index c66a60bc..d447ac02 100644 ---- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp -+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp -@@ -4,7 +4,9 @@ - Copyright (c) Microsoft Corporation - SPDX-License-Identifier: BSD-2-Clause-Patent - **/ --#include -+#include -+#include -+#include - - extern "C" { - #include -@@ -19,7 +21,8 @@ extern "C" { - // Definitions - /////////////////////////////////////////////////////////////////////////////// - --#define PACKET_SIZE (1500) -+#define PACKET_SIZE (1500) -+#define REQUEST_OPTION_LENGTH (120) - - typedef struct { - UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03) -@@ -76,6 +79,26 @@ MockConfigure ( - } - - // Needed by PxeBcSupport -+EFI_STATUS -+PxeBcDns6 ( -+ IN PXEBC_PRIVATE_DATA *Private, -+ IN CHAR16 *HostName, -+ OUT EFI_IPv6_ADDRESS *IpAddress -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ -+UINT32 -+PxeBcBuildDhcp6Options ( -+ IN PXEBC_PRIVATE_DATA *Private, -+ OUT EFI_DHCP6_PACKET_OPTION **OptList, -+ IN UINT8 *Buffer -+ ) -+{ -+ return EFI_SUCCESS; -+} -+ - EFI_STATUS - EFIAPI - QueueDpc ( -@@ -159,6 +182,10 @@ TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) { - ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR); - } - -+/////////////////////////////////////////////////////////////////////////////// -+// PxeBcCacheDnsServerAddresses Tests -+/////////////////////////////////////////////////////////////////////////////// -+ - class PxeBcCacheDnsServerAddressesTest : public ::testing::Test { - public: - PXEBC_PRIVATE_DATA Private = { 0 }; -@@ -298,3 +325,250 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { - FreePool (Private.DnsServer); - } - } -+ -+/////////////////////////////////////////////////////////////////////////////// -+// PxeBcRequestBootServiceTest Test Cases -+/////////////////////////////////////////////////////////////////////////////// -+ -+class PxeBcRequestBootServiceTest : public ::testing::Test { -+public: -+ PXEBC_PRIVATE_DATA Private = { 0 }; -+ EFI_UDP6_PROTOCOL Udp6Read; -+ -+protected: -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); -+ -+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL -+ // The function under test really only needs the following: -+ // UdpWrite -+ // UdpRead -+ -+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; -+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; -+ -+ // Need to setup EFI_UDP6_PROTOCOL -+ // The function under test really only needs the following: -+ // Configure -+ -+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure; -+ Private.Udp6Read = &Udp6Read; -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ if (Private.Dhcp6Request != NULL) { -+ FreePool (Private.Dhcp6Request); -+ } -+ -+ // Clean up any resources or variables -+ } -+}; -+ -+TEST_F (PxeBcRequestBootServiceTest, ServerDiscoverBasicUsageTest) { -+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl; -+ -+ DHCP6_OPTION_SERVER_ID Server = { 0 }; -+ -+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID); -+ Server.OptionLen = HTONS (16); // valid length -+ UINT8 Index = 0; -+ -+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer; -+ -+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); -+ -+ CopyMem (Cursor, &Server, sizeof (Server)); -+ Cursor += sizeof (Server); -+ -+ // Update the packet length -+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); -+ Packet->Size = PACKET_SIZE; -+ -+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS); -+} -+ -+TEST_F (PxeBcRequestBootServiceTest, AttemptDiscoverOverFlowExpectFailure) { -+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl; -+ -+ DHCP6_OPTION_SERVER_ID Server = { 0 }; -+ -+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID); -+ Server.OptionLen = HTONS (1500); // This length would overflow without a check -+ UINT8 Index = 0; -+ -+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer; -+ -+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); -+ -+ CopyMem (Cursor, &Server, sizeof (Server)); -+ Cursor += sizeof (Server); -+ -+ // Update the packet length -+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); -+ Packet->Size = PACKET_SIZE; -+ -+ // This is going to be stopped by the duid overflow check -+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_INVALID_PARAMETER); -+} -+ -+TEST_F (PxeBcRequestBootServiceTest, RequestBasicUsageTest) { -+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter -+ -+ RequestOpt.OpCode = HTONS (0x1337); -+ RequestOpt.OpLen = 0; // valid length -+ -+ UINT8 Index = 0; -+ -+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index]; -+ -+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); -+ -+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); -+ Cursor += sizeof (RequestOpt); -+ -+ // Update the packet length -+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); -+ Packet->Size = PACKET_SIZE; -+ -+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS); -+} -+ -+TEST_F (PxeBcRequestBootServiceTest, AttemptRequestOverFlowExpectFailure) { -+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter -+ -+ RequestOpt.OpCode = HTONS (0x1337); -+ RequestOpt.OpLen = 1500; // this length would overflow without a check -+ -+ UINT8 Index = 0; -+ -+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index]; -+ -+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); -+ -+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); -+ Cursor += sizeof (RequestOpt); -+ -+ // Update the packet length -+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); -+ Packet->Size = PACKET_SIZE; -+ -+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_OUT_OF_RESOURCES); -+} -+ -+/////////////////////////////////////////////////////////////////////////////// -+// PxeBcDhcp6Discover Test -+/////////////////////////////////////////////////////////////////////////////// -+ -+class PxeBcDhcp6DiscoverTest : public ::testing::Test { -+public: -+ PXEBC_PRIVATE_DATA Private = { 0 }; -+ EFI_UDP6_PROTOCOL Udp6Read; -+ -+protected: -+ MockUefiRuntimeServicesTableLib RtServicesMock; -+ -+ // Add any setup code if needed -+ virtual void -+ SetUp ( -+ ) -+ { -+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); -+ -+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL -+ // The function under test really only needs the following: -+ // UdpWrite -+ // UdpRead -+ -+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; -+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; -+ -+ // Need to setup EFI_UDP6_PROTOCOL -+ // The function under test really only needs the following: -+ // Configure -+ -+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure; -+ Private.Udp6Read = &Udp6Read; -+ } -+ -+ // Add any cleanup code if needed -+ virtual void -+ TearDown ( -+ ) -+ { -+ if (Private.Dhcp6Request != NULL) { -+ FreePool (Private.Dhcp6Request); -+ } -+ -+ // Clean up any resources or variables -+ } -+}; -+ -+// Test Description -+// This will cause an overflow by an untrusted packet during the option parsing -+TEST_F (PxeBcDhcp6DiscoverTest, BasicOverflowTest) { -+ EFI_IPv6_ADDRESS DestIp = { 0 }; -+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter -+ -+ RequestOpt.OpCode = HTONS (0x1337); -+ RequestOpt.OpLen = HTONS (0xFFFF); // overflow -+ -+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option); -+ -+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); -+ Cursor += sizeof (RequestOpt); -+ -+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request); -+ -+ EXPECT_CALL (RtServicesMock, gRT_GetTime) -+ .WillOnce (::testing::Return (0)); -+ -+ ASSERT_EQ ( -+ PxeBcDhcp6Discover ( -+ &(PxeBcDhcp6DiscoverTest::Private), -+ 0, -+ NULL, -+ FALSE, -+ (EFI_IP_ADDRESS *)&DestIp -+ ), -+ EFI_OUT_OF_RESOURCES -+ ); -+} -+ -+// Test Description -+// This will test that we can handle a packet with a valid option length -+TEST_F (PxeBcDhcp6DiscoverTest, BasicUsageTest) { -+ EFI_IPv6_ADDRESS DestIp = { 0 }; -+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter -+ -+ RequestOpt.OpCode = HTONS (0x1337); -+ RequestOpt.OpLen = HTONS (0x30); -+ -+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option); -+ -+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); -+ Cursor += sizeof (RequestOpt); -+ -+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request); -+ -+ EXPECT_CALL (RtServicesMock, gRT_GetTime) -+ .WillOnce (::testing::Return (0)); -+ -+ ASSERT_EQ ( -+ PxeBcDhcp6Discover ( -+ &(PxeBcDhcp6DiscoverTest::Private), -+ 0, -+ NULL, -+ FALSE, -+ (EFI_IP_ADDRESS *)&DestIp -+ ), -+ EFI_SUCCESS -+ ); -+} -diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h -index 48ab238d..4c6173de 100644 ---- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h -+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h -@@ -47,4 +47,22 @@ PxeBcCacheDnsServerAddresses ( - IN PXEBC_DHCP6_PACKET_CACHE *Cache6 - ); - -+/** -+ Build and send out the request packet for the bootfile, and parse the reply. -+ -+ @param[in] Private The pointer to PxeBc private data. -+ @param[in] Index PxeBc option boot item type. -+ -+ @retval EFI_SUCCESS Successfully discovered the boot file. -+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. -+ @retval EFI_NOT_FOUND Can't get the PXE reply packet. -+ @retval Others Failed to discover the boot file. -+ -+**/ -+EFI_STATUS -+PxeBcRequestBootService ( -+ IN PXEBC_PRIVATE_DATA *Private, -+ IN UINT32 Index -+ ); -+ - #endif // PXE_BC_DHCP6_GOOGLE_TEST_H_ --- -2.33.0 - diff --git a/0035-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch b/0035-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch deleted file mode 100644 index ca1fd2ad0e729c3721f34e2cfac3fdceda93ce4d..0000000000000000000000000000000000000000 --- a/0035-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch +++ /dev/null @@ -1,154 +0,0 @@ -From e8d9e9ac34f4efca3651309fdb3d023419fb3f68 Mon Sep 17 00:00:00 2001 -From: "Doug Flick via groups.io" -Date: Fri, 26 Jan 2024 05:54:57 +0800 -Subject: [PATCH 15/19] NetworkPkg: : Adds a SecurityFix.yaml file - -This creates / adds a security file that tracks the security fixes -found in this package and can be used to find the fixes that were -applied. - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams - -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar - -reference: https://github.com/tianocore/edk2/pull/5352 -Signed-off-by: yexiao ---- - NetworkPkg/SecurityFixes.yaml | 123 ++++++++++++++++++++++++++++++++++ - 1 file changed, 123 insertions(+) - create mode 100644 NetworkPkg/SecurityFixes.yaml - -diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml -new file mode 100644 -index 00000000..0b37bbda ---- /dev/null -+++ b/NetworkPkg/SecurityFixes.yaml -@@ -0,0 +1,123 @@ -+## @file -+# Security Fixes for SecurityPkg -+# -+# Copyright (c) Microsoft Corporation -+# SPDX-License-Identifier: BSD-2-Clause-Patent -+## -+CVE_2023_45229: -+ commit_titles: -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests" -+ cve: CVE-2023-45229 -+ date_reported: 2023-08-28 13:56 UTC -+ description: "Bug 01 - edk2/NetworkPkg: Out-of-bounds read when processing IA_NA/IA_TA options in a DHCPv6 Advertise message" -+ note: -+ files_impacted: -+ - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c -+ - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4534 -+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45229 -+ - http://www.openwall.com/lists/oss-security/2024/01/16/2 -+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html -+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html -+CVE_2023_45230: -+ commit_titles: -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests" -+ cve: CVE-2023-45230 -+ date_reported: 2023-08-28 13:56 UTC -+ description: "Bug 02 - edk2/NetworkPkg: Buffer overflow in the DHCPv6 client via a long Server ID option" -+ note: -+ files_impacted: -+ - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c -+ - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4535 -+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45230 -+ - http://www.openwall.com/lists/oss-security/2024/01/16/2 -+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html -+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html -+CVE_2023_45231: -+ commit_titles: -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Patch" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Unit Tests" -+ cve: CVE-2023-45231 -+ date_reported: 2023-08-28 13:56 UTC -+ description: "Bug 03 - edk2/NetworkPkg: Out-of-bounds read when handling a ND Redirect message with truncated options" -+ note: -+ files_impacted: -+ - NetworkPkg/Ip6Dxe/Ip6Option.c -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4536 -+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45231 -+ - http://www.openwall.com/lists/oss-security/2024/01/16/2 -+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html -+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html -+CVE_2023_45232: -+ commit_titles: -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests" -+ cve: CVE-2023-45232 -+ date_reported: 2023-08-28 13:56 UTC -+ description: "Bug 04 - edk2/NetworkPkg: Infinite loop when parsing unknown options in the Destination Options header" -+ note: -+ files_impacted: -+ - NetworkPkg/Ip6Dxe/Ip6Option.c -+ - NetworkPkg/Ip6Dxe/Ip6Option.h -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4537 -+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45232 -+ - http://www.openwall.com/lists/oss-security/2024/01/16/2 -+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html -+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html -+CVE_2023_45233: -+ commit_titles: -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests" -+ cve: CVE-2023-45233 -+ date_reported: 2023-08-28 13:56 UTC -+ description: "Bug 05 - edk2/NetworkPkg: Infinite loop when parsing a PadN option in the Destination Options header " -+ note: This was fixed along with CVE-2023-45233 -+ files_impacted: -+ - NetworkPkg/Ip6Dxe/Ip6Option.c -+ - NetworkPkg/Ip6Dxe/Ip6Option.h -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4538 -+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45233 -+ - http://www.openwall.com/lists/oss-security/2024/01/16/2 -+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html -+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html -+CVE_2023_45234: -+ commit_titles: -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Patch" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Unit Tests" -+ cve: CVE-2023-45234 -+ date_reported: 2023-08-28 13:56 UTC -+ description: "Bug 06 - edk2/NetworkPkg: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message" -+ note: -+ files_impacted: -+ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4539 -+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45234 -+ - http://www.openwall.com/lists/oss-security/2024/01/16/2 -+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html -+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html -+CVE_2023_45235: -+ commit_titles: -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Patch" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Unit Tests" -+ cve: CVE-2023-45235 -+ date_reported: 2023-08-28 13:56 UTC -+ description: "Bug 07 - edk2/NetworkPkg: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message" -+ note: -+ files_impacted: -+ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c -+ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h -+ links: -+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4540 -+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45235 -+ - http://www.openwall.com/lists/oss-security/2024/01/16/2 -+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html -+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html --- -2.33.0 - diff --git a/0036-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch b/0036-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch deleted file mode 100644 index c7277ca0c33e801252e6933f8c4887617ee54bb7..0000000000000000000000000000000000000000 --- a/0036-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch +++ /dev/null @@ -1,241 +0,0 @@ -From 224d9dad3626a13bd0d2f949b898f34c05b6fec4 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Tue, 13 Feb 2024 10:46:00 -0800 -Subject: [PATCH 16/19] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 - Related Patch - -REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4673 -REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534 - -This was not part of the Quarkslab bugs however the same pattern -as CVE-2023-45229 exists in Dhcp6UpdateIaInfo. - -This patch replaces the code in question with the safe function -created to patch CVE-2023-45229 - -> -> if (EFI_ERROR ( -> Dhcp6SeekInnerOptionSafe ( -> Instance->Config->IaDescriptor.Type, -> Option, -> OptionLen, -> &IaInnerOpt, -> &IaInnerLen -> ) -> )) -> { -> return EFI_DEVICE_ERROR; -> } -> - -Additionally corrects incorrect usage of macro to read the status - -> - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN - (Option))); -> + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) -DHCP6_OFFSET_OF_STATUS_CODE (Option)); - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar -Reviewed-by: Leif Lindholm - -reference: https://github.com/tianocore/edk2/pull/5372 -Signed-off-by: yexiao ---- - NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 70 ++++++++++++++++++++++++++--------- - NetworkPkg/Dhcp6Dxe/Dhcp6Io.h | 22 +++++++++++ - 2 files changed, 75 insertions(+), 17 deletions(-) - -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -index afec4eff..88c7a4c4 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c -@@ -528,13 +528,23 @@ Dhcp6UpdateIaInfo ( - { - EFI_STATUS Status; - UINT8 *Option; -+ UINT32 OptionLen; - UINT8 *IaInnerOpt; - UINT16 IaInnerLen; - UINT16 StsCode; - UINT32 T1; - UINT32 T2; - -+ T1 = 0; -+ T2 = 0; -+ - ASSERT (Instance->Config != NULL); -+ -+ // OptionLen is the length of the Options excluding the DHCP header. -+ // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last -+ // byte of the Option[] field. -+ OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); -+ - // - // If the reply was received in response to a solicit with rapid commit option, - // request, renew or rebind message, the client updates the information it has -@@ -549,13 +559,29 @@ Dhcp6UpdateIaInfo ( - // - Option = Dhcp6SeekIaOption ( - Packet->Dhcp6.Option, -- Packet->Length - sizeof (EFI_DHCP6_HEADER), -+ OptionLen, - &Instance->Config->IaDescriptor - ); - if (Option == NULL) { - return EFI_DEVICE_ERROR; - } - -+ // -+ // Calculate the distance from Packet->Dhcp6.Option to the IA option. -+ // -+ // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is -+ // the size of the whole packet, including the DHCP header, and Packet->Length -+ // is the length of the DHCP message body, excluding the DHCP header. -+ // -+ // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of -+ // DHCP6 option area to the start of the IA option. -+ // -+ // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the -+ // IA option to the end of the DHCP6 option area, thus subtract the space -+ // up until this option -+ // -+ OptionLen = OptionLen - (UINT32)(Option - Packet->Dhcp6.Option); -+ - // - // The format of the IA_NA option is: - // -@@ -591,32 +617,32 @@ Dhcp6UpdateIaInfo ( - // - - // -- // sizeof (option-code + option-len + IaId) = 8 -- // sizeof (option-code + option-len + IaId + T1) = 12 -- // sizeof (option-code + option-len + IaId + T1 + T2) = 16 -- // -- // The inner options still start with 2 bytes option-code and 2 bytes option-len. -+ // Seek the inner option - // -+ if (EFI_ERROR ( -+ Dhcp6SeekInnerOptionSafe ( -+ Instance->Config->IaDescriptor.Type, -+ Option, -+ OptionLen, -+ &IaInnerOpt, -+ &IaInnerLen -+ ) -+ )) -+ { -+ return EFI_DEVICE_ERROR; -+ } -+ - if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { - T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); - T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); - // - // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2, - // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes -- // the remainder of the message as though the server had not included the invalid IA_NA option. -+ // the remainder of the message as though the server had not included the invalid IA_NA option. - // - if ((T1 > T2) && (T2 > 0)) { - return EFI_DEVICE_ERROR; - } -- -- IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); -- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); -- } else { -- T1 = 0; -- T2 = 0; -- -- IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); -- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID); - } - - // -@@ -642,7 +668,7 @@ Dhcp6UpdateIaInfo ( - Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); - - if (Option != NULL) { -- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); -+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (Option)))); - if (StsCode != Dhcp6StsSuccess) { - return EFI_DEVICE_ERROR; - } -@@ -703,15 +729,21 @@ Dhcp6SeekInnerOptionSafe ( - } - - if (IaType == Dhcp6OptIana) { -+ // - // Verify we have a fully formed IA_NA -+ // - if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { - return EFI_DEVICE_ERROR; - } - -+ // -+ // Get the IA Inner Option and Length - // - IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); - -+ // - // Verify the IaInnerLen is valid. -+ // - IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); - if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { - return EFI_DEVICE_ERROR; -@@ -719,14 +751,18 @@ Dhcp6SeekInnerOptionSafe ( - - IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; - } else if (IaType == Dhcp6OptIata) { -+ // - // Verify the OptionLen is valid. -+ // - if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { - return EFI_DEVICE_ERROR; - } - - IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); - -+ // - // Verify the IaInnerLen is valid. -+ // - IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); - if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { - return EFI_DEVICE_ERROR; -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h -index 051a652f..5e53ba69 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h -@@ -217,4 +217,26 @@ Dhcp6OnTimerTick ( - IN VOID *Context - ); - -+/** -+ Seeks the Inner Options from a DHCP6 Option -+ -+ @param[in] IaType The type of the IA option. -+ @param[in] Option The pointer to the DHCP6 Option. -+ @param[in] OptionLen The length of the DHCP6 Option. -+ @param[out] IaInnerOpt The pointer to the IA inner option. -+ @param[out] IaInnerLen The length of the IA inner option. -+ -+ @retval EFI_SUCCESS Seek the inner option successfully. -+ @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, -+ the pointers are not modified -+**/ -+EFI_STATUS -+Dhcp6SeekInnerOptionSafe ( -+ IN UINT16 IaType, -+ IN UINT8 *Option, -+ IN UINT32 OptionLen, -+ OUT UINT8 **IaInnerOpt, -+ OUT UINT16 *IaInnerLen -+ ); -+ - #endif --- -2.33.0 - diff --git a/0037-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch b/0037-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch deleted file mode 100644 index e092af53e97fb77f7b8fefde5a768f261afd1743..0000000000000000000000000000000000000000 --- a/0037-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 665b076fc6082d3e7637c0952e1cf0d4a3104bc7 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Tue, 13 Feb 2024 10:46:01 -0800 -Subject: [PATCH 17/19] NetworkPkg: Dhcp6Dxe: Removes duplicate check and - replaces with macro - -Removes duplicate check after merge - -> -> // -> // Verify the PacketCursor is within the packet -> // -> if ( (*PacketCursor < Packet->Dhcp6.Option) -> || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - -sizeof (EFI_DHCP6_HEADER)))) -> { -> return EFI_INVALID_PARAMETER; -> } -> - -Converts the check to a macro and replaces all instances of the check -with the macro - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar -Reviewed-by: Leif Lindholm - -reference: https://github.com/tianocore/edk2/pull/5372 -Signed-off-by: yexiao ---- - NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 44 +++++++++++++----------------- - 1 file changed, 19 insertions(+), 25 deletions(-) - -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -index e9c45072..db9e02a1 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -@@ -10,6 +10,16 @@ - - #include "Dhcp6Impl.h" - -+// -+// Verifies the packet cursor is within the packet -+// otherwise it is invalid -+// -+#define IS_INVALID_PACKET_CURSOR(PacketCursor, Packet) \ -+ (((*PacketCursor) < (Packet)->Dhcp6.Option) || \ -+ ((*PacketCursor) >= (Packet)->Dhcp6.Option + ((Packet)->Size - sizeof(EFI_DHCP6_HEADER))) \ -+ ) \ -+ -+ - /** - Generate client Duid in the format of Duid-llt. - -@@ -638,9 +648,7 @@ Dhcp6AppendOption ( - // - // Verify the PacketCursor is within the packet - // -- if ( (*PacketCursor < Packet->Dhcp6.Option) -- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -- { -+ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { - return EFI_INVALID_PARAMETER; - } - -@@ -657,15 +665,6 @@ Dhcp6AppendOption ( - return EFI_BUFFER_TOO_SMALL; - } - -- // -- // Verify the PacketCursor is within the packet -- // -- if ( (*PacketCursor < Packet->Dhcp6.Option) -- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -- { -- return EFI_INVALID_PARAMETER; -- } -- - WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); - *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; - WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); -@@ -744,9 +743,7 @@ Dhcp6AppendIaAddrOption ( - // - // Verify the PacketCursor is within the packet - // -- if ( (*PacketCursor < Packet->Dhcp6.Option) -- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -- { -+ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { - return EFI_INVALID_PARAMETER; - } - -@@ -877,9 +874,7 @@ Dhcp6AppendIaOption ( - // - // Verify the PacketCursor is within the packet - // -- if ( (*PacketCursor < Packet->Dhcp6.Option) -- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -- { -+ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { - return EFI_INVALID_PARAMETER; - } - -@@ -941,14 +936,14 @@ Dhcp6AppendIaOption ( - } - - // -- // Fill the value of Ia option length -+ // Update the packet length - // -- *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); -+ Packet->Length += BytesNeeded; - - // -- // Update the packet length -+ // Fill the value of Ia option length - // -- Packet->Length += BytesNeeded; -+ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); - - return EFI_SUCCESS; - } -@@ -957,6 +952,7 @@ Dhcp6AppendIaOption ( - Append the appointed Elapsed time option to Buf, and move Buf to the end. - - @param[in, out] Packet A pointer to the packet, on success Packet->Length -+ will be updated. - @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor - will be moved to the end of the option. - @param[in] Instance The pointer to the Dhcp6 instance. -@@ -1012,9 +1008,7 @@ Dhcp6AppendETOption ( - // - // Verify the PacketCursor is within the packet - // -- if ( (*PacketCursor < Packet->Dhcp6.Option) -- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) -- { -+ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { - return EFI_INVALID_PARAMETER; - } - --- -2.33.0 - diff --git a/0038-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch b/0038-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch deleted file mode 100644 index 911158deb1835a30fb33a2ffd98639cd251d2a72..0000000000000000000000000000000000000000 --- a/0038-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch +++ /dev/null @@ -1,53 +0,0 @@ -From f656a38b052e4eb47a2a2fd1e53c979acdf74b03 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Tue, 13 Feb 2024 10:46:02 -0800 -Subject: [PATCH 18/19] NetworkPkg: Dhcp6Dxe: Packet-Length is not updated - before appending - -In order for Dhcp6AppendIaAddrOption (..) to safely append the IA -Address option, the Packet-Length field must be updated before appending -the option. - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar -Reviewed-by: Leif Lindholm - -reference: https://github.com/tianocore/edk2/pull/5372 -Signed-off-by: yexiao ---- - NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -index db9e02a1..7d4d5452 100644 ---- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c -@@ -924,6 +924,11 @@ Dhcp6AppendIaOption ( - *PacketCursor += sizeof (T2); - } - -+ // -+ // Update the packet length -+ // -+ Packet->Length += BytesNeeded; -+ - // - // Fill all the addresses belong to the Ia - // -@@ -935,11 +940,6 @@ Dhcp6AppendIaOption ( - } - } - -- // -- // Update the packet length -- // -- Packet->Length += BytesNeeded; -- - // - // Fill the value of Ia option length - // --- -2.33.0 - diff --git a/0039-NetworkPkg-Updating-SecurityFixes.yaml.patch b/0039-NetworkPkg-Updating-SecurityFixes.yaml.patch deleted file mode 100644 index e054ea4c611893a904eeee8d583a328506fa802e..0000000000000000000000000000000000000000 --- a/0039-NetworkPkg-Updating-SecurityFixes.yaml.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 07a04bb21a4c6c55aa63cfacdab3e621e847f951 Mon Sep 17 00:00:00 2001 -From: Doug Flick -Date: Tue, 13 Feb 2024 10:46:03 -0800 -Subject: [PATCH 19/19] NetworkPkg: : Updating SecurityFixes.yaml - -This captures the related security change for Dhcp6Dxe that is related -to CVE-2023-45229 - -Cc: Saloni Kasbekar -Cc: Zachary Clark-williams -Signed-off-by: Doug Flick [MSFT] -Reviewed-by: Saloni Kasbekar -Reviewed-by: Leif Lindholm - -reference: https://github.com/tianocore/edk2/pull/5372 -Signed-off-by: yexiao ---- - NetworkPkg/SecurityFixes.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml -index 0b37bbda..7d716ffc 100644 ---- a/NetworkPkg/SecurityFixes.yaml -+++ b/NetworkPkg/SecurityFixes.yaml -@@ -8,6 +8,7 @@ CVE_2023_45229: - commit_titles: - - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch" - - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests" -+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Related Patch" - cve: CVE-2023-45229 - date_reported: 2023-08-28 13:56 UTC - description: "Bug 01 - edk2/NetworkPkg: Out-of-bounds read when processing IA_NA/IA_TA options in a DHCPv6 Advertise message" --- -2.33.0 - diff --git a/0040-Add-a-test-for-session-cache-handling.patch b/0040-Add-a-test-for-session-cache-handling.patch deleted file mode 100644 index b3627be15598c15a603008f969a4069e7b86c28a..0000000000000000000000000000000000000000 --- a/0040-Add-a-test-for-session-cache-handling.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 380d1ef504e3dae8f6b44a345f0fc800d783b9ac Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Mon, 4 Mar 2024 13:45:23 +0000 -Subject: [PATCH 1/5] Add a test for session cache handling - -Repeatedly create sessions to be added to the cache and ensure we never -exceed the expected size. - -Related to CVE-2024-2511 - -Reviewed-by: Neil Horman -Reviewed-by: Tomas Mraz -(Merged from https://github.com/openssl/openssl/pull/24042) - -reference: https://github.com/openssl/openssl/pull/24042 -Signed-off-by: shenyage ---- - .../OpensslLib/openssl/test/sslapitest.c | 92 +++++++++++++++++++ - 1 file changed, 92 insertions(+) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -index 3d57101..8ed3524 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -@@ -10303,6 +10303,97 @@ end: - } - #endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) */ - -+/* -+ * Test multiple resumptions and cache size handling -+ * Test 0: TLSv1.3 (max_early_data set) -+ * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set) -+ * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set) -+ * Test 3: TLSv1.2 -+ */ -+static int test_multi_resume(int idx) -+{ -+ SSL_CTX *sctx = NULL, *cctx = NULL; -+ SSL *serverssl = NULL, *clientssl = NULL; -+ SSL_SESSION *sess = NULL; -+ int max_version = TLS1_3_VERSION; -+ int i, testresult = 0; -+ -+ if (idx == 3) -+ max_version = TLS1_2_VERSION; -+ -+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), -+ TLS_client_method(), TLS1_VERSION, -+ max_version, &sctx, &cctx, cert, -+ privkey))) -+ goto end; -+ -+ /* -+ * TLSv1.3 only uses a session cache if either max_early_data > 0 (used for -+ * replay protection), or if SSL_OP_NO_TICKET is in use -+ */ -+ if (idx == 0 || idx == 2) { -+ if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024))) -+ goto end; -+ } -+ if (idx == 1 || idx == 2) -+ SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET); -+ -+ SSL_CTX_sess_set_cache_size(sctx, 5); -+ -+ for (i = 0; i < 30; i++) { -+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, -+ NULL, NULL)) -+ || !TEST_true(SSL_set_session(clientssl, sess))) -+ goto end; -+ -+ /* -+ * Recreate a bug where dynamically changing the max_early_data value -+ * can cause sessions in the session cache which cannot be deleted. -+ */ -+ if ((idx == 0 || idx == 2) && (i % 3) == 2) -+ SSL_set_max_early_data(serverssl, 0); -+ -+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) -+ goto end; -+ -+ if (sess == NULL || (idx == 0 && (i % 3) == 2)) { -+ if (!TEST_false(SSL_session_reused(clientssl))) -+ goto end; -+ } else { -+ if (!TEST_true(SSL_session_reused(clientssl))) -+ goto end; -+ } -+ SSL_SESSION_free(sess); -+ -+ /* Do a full handshake, followed by two resumptions */ -+ if ((i % 3) == 2) { -+ sess = NULL; -+ } else { -+ if (!TEST_ptr((sess = SSL_get1_session(clientssl)))) -+ goto end; -+ } -+ -+ SSL_shutdown(clientssl); -+ SSL_shutdown(serverssl); -+ SSL_free(serverssl); -+ SSL_free(clientssl); -+ serverssl = clientssl = NULL; -+ } -+ -+ /* We should never exceed the session cache size limit */ -+ if (!TEST_long_le(SSL_CTX_sess_number(sctx), 5)) -+ goto end; -+ -+ testresult = 1; -+ end: -+ SSL_free(serverssl); -+ SSL_free(clientssl); -+ SSL_CTX_free(sctx); -+ SSL_CTX_free(cctx); -+ SSL_SESSION_free(sess); -+ return testresult; -+} -+ - OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n") - - int setup_tests(void) -@@ -10574,6 +10665,7 @@ int setup_tests(void) - #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) - ADD_ALL_TESTS(test_pipelining, 6); - #endif -+ ADD_ALL_TESTS(test_multi_resume, 4); - return 1; - - err: --- -2.33.0 - diff --git a/0041-Extend-the-multi_resume-test-for-simultaneous-resump.patch b/0041-Extend-the-multi_resume-test-for-simultaneous-resump.patch deleted file mode 100644 index d6a86f9cbd33339b5043c91bb6ad11a5e07f3b68..0000000000000000000000000000000000000000 --- a/0041-Extend-the-multi_resume-test-for-simultaneous-resump.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 4023a42e26e3c476c6989e2c5bf2db08937e0df8 Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Tue, 5 Mar 2024 15:35:51 +0000 -Subject: [PATCH 2/5] Extend the multi_resume test for simultaneous resumptions - -Test what happens if the same session gets resumed multiple times at the -same time - and one of them gets marked as not_resumable. - -Related to CVE-2024-2511 - -Reviewed-by: Neil Horman -Reviewed-by: Tomas Mraz -(Merged from https://github.com/openssl/openssl/pull/24042) - -reference: https://github.com/openssl/openssl/pull/24042 -Signed-off-by: shenyage ---- - .../OpensslLib/openssl/test/sslapitest.c | 88 ++++++++++++++++++- - 1 file changed, 84 insertions(+), 4 deletions(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -index 8ed3524..0529793 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -@@ -10303,12 +10303,62 @@ end: - } - #endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) */ - -+struct resume_servername_cb_data { -+ int i; -+ SSL_CTX *cctx; -+ SSL_CTX *sctx; -+ SSL_SESSION *sess; -+ int recurse; -+}; -+ -+/* -+ * Servername callback. We use it here to run another complete handshake using -+ * the same session - and mark the session as not_resuamble at the end -+ */ -+static int resume_servername_cb(SSL *s, int *ad, void *arg) -+{ -+ struct resume_servername_cb_data *cbdata = arg; -+ SSL *serverssl = NULL, *clientssl = NULL; -+ int ret = SSL_TLSEXT_ERR_ALERT_FATAL; -+ -+ if (cbdata->recurse) -+ return SSL_TLSEXT_ERR_ALERT_FATAL; -+ -+ if ((cbdata->i % 3) != 1) -+ return SSL_TLSEXT_ERR_OK; -+ -+ cbdata->recurse = 1; -+ -+ if (!TEST_true(create_ssl_objects(cbdata->sctx, cbdata->cctx, &serverssl, -+ &clientssl, NULL, NULL)) -+ || !TEST_true(SSL_set_session(clientssl, cbdata->sess))) -+ goto end; -+ -+ ERR_set_mark(); -+ /* -+ * We expect this to fail - because the servername cb will fail. This will -+ * mark the session as not_resumable. -+ */ -+ if (!TEST_false(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) { -+ ERR_clear_last_mark(); -+ goto end; -+ } -+ ERR_pop_to_mark(); -+ -+ ret = SSL_TLSEXT_ERR_OK; -+ end: -+ SSL_free(serverssl); -+ SSL_free(clientssl); -+ cbdata->recurse = 0; -+ return ret; -+} - /* - * Test multiple resumptions and cache size handling - * Test 0: TLSv1.3 (max_early_data set) - * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set) - * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set) -- * Test 3: TLSv1.2 -+ * Test 3: TLSv1.3 (SSL_OP_NO_TICKET, simultaneous resumes) -+ * Test 4: TLSv1.2 - */ - static int test_multi_resume(int idx) - { -@@ -10317,9 +10367,19 @@ static int test_multi_resume(int idx) - SSL_SESSION *sess = NULL; - int max_version = TLS1_3_VERSION; - int i, testresult = 0; -+ struct resume_servername_cb_data cbdata; - -- if (idx == 3) -+#if defined(OPENSSL_NO_TLS1_2) -+ if (idx == 4) -+ return TEST_skip("TLSv1.2 is disabled in this build"); -+#else -+ if (idx == 4) - max_version = TLS1_2_VERSION; -+#endif -+#if defined(OSSL_NO_USABLE_TLS1_3) -+ if (idx != 4) -+ return TEST_skip("No usable TLSv1.3 in this build"); -+#endif - - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, -@@ -10335,17 +10395,37 @@ static int test_multi_resume(int idx) - if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024))) - goto end; - } -- if (idx == 1 || idx == 2) -+ if (idx == 1 || idx == 2 || idx == 3) - SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET); - - SSL_CTX_sess_set_cache_size(sctx, 5); - -+ if (idx == 3) { -+ SSL_CTX_set_tlsext_servername_callback(sctx, resume_servername_cb); -+ SSL_CTX_set_tlsext_servername_arg(sctx, &cbdata); -+ cbdata.cctx = cctx; -+ cbdata.sctx = sctx; -+ cbdata.recurse = 0; -+ } -+ - for (i = 0; i < 30; i++) { - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, - NULL, NULL)) - || !TEST_true(SSL_set_session(clientssl, sess))) - goto end; - -+ /* -+ * Check simultaneous resumes. We pause the connection part way through -+ * the handshake by (mis)using the servername_cb. The pause occurs after -+ * session resumption has already occurred, but before any session -+ * tickets have been issued. While paused we run another complete -+ * handshake resuming the same session. -+ */ -+ if (idx == 3) { -+ cbdata.i = i; -+ cbdata.sess = sess; -+ } -+ - /* - * Recreate a bug where dynamically changing the max_early_data value - * can cause sessions in the session cache which cannot be deleted. -@@ -10665,7 +10745,7 @@ int setup_tests(void) - #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) - ADD_ALL_TESTS(test_pipelining, 6); - #endif -- ADD_ALL_TESTS(test_multi_resume, 4); -+ ADD_ALL_TESTS(test_multi_resume, 5); - return 1; - - err: --- -2.33.0 - diff --git a/0042-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch b/0042-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch deleted file mode 100644 index 8160d09779c52c396621dbfa03f988577db7ef9c..0000000000000000000000000000000000000000 --- a/0042-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch +++ /dev/null @@ -1,122 +0,0 @@ -From ff3df21663344b334aa2a06a3e83cb3a2552f072 Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Tue, 5 Mar 2024 15:43:53 +0000 -Subject: [PATCH 3/5] Fix unconstrained session cache growth in TLSv1.3 - -In TLSv1.3 we create a new session object for each ticket that we send. -We do this by duplicating the original session. If SSL_OP_NO_TICKET is in -use then the new session will be added to the session cache. However, if -early data is not in use (and therefore anti-replay protection is being -used), then multiple threads could be resuming from the same session -simultaneously. If this happens and a problem occurs on one of the threads, -then the original session object could be marked as not_resumable. When we -duplicate the session object this not_resumable status gets copied into the -new session object. The new session object is then added to the session -cache even though it is not_resumable. - -Subsequently, another bug means that the session_id_length is set to 0 for -sessions that are marked as not_resumable - even though that session is -still in the cache. Once this happens the session can never be removed from -the cache. When that object gets to be the session cache tail object the -cache never shrinks again and grows indefinitely. - -CVE-2024-2511 - -Reviewed-by: Neil Horman -Reviewed-by: Tomas Mraz -(Merged from https://github.com/openssl/openssl/pull/24042) - -reference: https://github.com/openssl/openssl/pull/24042 -Signed-off-by: shenyage ---- - .../Library/OpensslLib/openssl/ssl/ssl_lib.c | 5 ++-- - .../Library/OpensslLib/openssl/ssl/ssl_sess.c | 28 +++++++++++++++---- - .../openssl/ssl/statem/statem_srvr.c | 5 ++-- - 3 files changed, 27 insertions(+), 11 deletions(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c -index 214884b..35420eb 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c -@@ -3717,9 +3717,10 @@ void ssl_update_cache(SSL *s, int mode) - - /* - * If the session_id_length is 0, we are not supposed to cache it, and it -- * would be rather hard to do anyway :-) -+ * would be rather hard to do anyway :-). Also if the session has already -+ * been marked as not_resumable we should not cache it for later reuse. - */ -- if (s->session->session_id_length == 0) -+ if (s->session->session_id_length == 0 || s->session->not_resumable) - return; - - /* -diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c -index c322a11..8f2f37b 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c -@@ -152,16 +152,11 @@ SSL_SESSION *SSL_SESSION_new(void) - return ss; - } - --SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src) --{ -- return ssl_session_dup(src, 1); --} -- - /* - * Create a new SSL_SESSION and duplicate the contents of |src| into it. If - * ticket == 0 then no ticket information is duplicated, otherwise it is. - */ --SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) -+static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket) - { - SSL_SESSION *dest; - -@@ -282,6 +277,27 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) - return NULL; - } - -+SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src) -+{ -+ return ssl_session_dup_intern(src, 1); -+} -+ -+/* -+ * Used internally when duplicating a session which might be already shared. -+ * We will have resumed the original session. Subsequently we might have marked -+ * it as non-resumable (e.g. in another thread) - but this copy should be ok to -+ * resume from. -+ */ -+SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) -+{ -+ SSL_SESSION *sess = ssl_session_dup_intern(src, ticket); -+ -+ if (sess != NULL) -+ sess->not_resumable = 0; -+ -+ return sess; -+} -+ - const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) - { - if (len) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c -index a9e67f9..70c1893 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c -@@ -2338,9 +2338,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) - * so the following won't overwrite an ID that we're supposed - * to send back. - */ -- if (s->session->not_resumable || -- (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) -- && !s->hit)) -+ if (!(SSL_CONNECTION_GET_CTX(s)->session_cache_mode & SSL_SESS_CACHE_SERVER) -+ && !s->hit) - s->session->session_id_length = 0; - - if (usetls13) { --- -2.33.0 - diff --git a/0043-Hardening-around-not_resumable-sessions.patch b/0043-Hardening-around-not_resumable-sessions.patch deleted file mode 100644 index a2503bb9a1b59a4b42cd3540f7a6691f413f82aa..0000000000000000000000000000000000000000 --- a/0043-Hardening-around-not_resumable-sessions.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c44d5f799061ed8d7174c58e0cef0e43bda185be Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Fri, 15 Mar 2024 17:58:42 +0000 -Subject: [PATCH 4/5] Hardening around not_resumable sessions - -Make sure we can't inadvertently use a not_resumable session - -Related to CVE-2024-2511 - -Reviewed-by: Neil Horman -Reviewed-by: Tomas Mraz -(Merged from https://github.com/openssl/openssl/pull/24042) - -reference: https://github.com/openssl/openssl/pull/24042 -Signed-off-by: shenyage ---- - CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c -index 8f2f37b..46f4f75 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c -@@ -528,6 +528,12 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, - ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, ©); - - if (ret != NULL) { -+ if (ret->not_resumable) { -+ /* If its not resumable then ignore this session */ -+ if (!copy) -+ SSL_SESSION_free(ret); -+ return NULL; -+ } - ssl_tsan_counter(s->session_ctx, - &s->session_ctx->stats.sess_cb_hit); - --- -2.33.0 - diff --git a/0044-Add-a-test-for-session-cache-overflow.patch b/0044-Add-a-test-for-session-cache-overflow.patch deleted file mode 100644 index b9216999fbeed256c78dfc1644a58e0aed331d2a..0000000000000000000000000000000000000000 --- a/0044-Add-a-test-for-session-cache-overflow.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 3ce388a7ea5c1e53dd10ea7d083f8de5c21adb54 Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Fri, 15 Jul 2022 13:26:33 +0100 -Subject: [PATCH 5/5] Add a test for session cache overflow - -Test sessions behave as we expect even in the case that an overflow -occurs when adding a new session into the session cache. - -Related to CVE-2024-2511 - -Reviewed-by: Neil Horman -Reviewed-by: Tomas Mraz -(Merged from https://github.com/openssl/openssl/pull/24042) - -reference: https://github.com/openssl/openssl/pull/24042 -Signed-off-by: shenyage ---- - .../OpensslLib/openssl/test/sslapitest.c | 124 +++++++++++++++++- - 1 file changed, 123 insertions(+), 1 deletion(-) - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -index 0529793..a8eed30 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c -@@ -2386,7 +2386,6 @@ static int test_session_wo_ca_names(void) - #endif - } - -- - #ifndef OSSL_NO_USABLE_TLS1_3 - static SSL_SESSION *sesscache[6]; - static int do_cache; -@@ -8938,6 +8937,126 @@ static int test_session_timeout(int test) - return testresult; - } - -+/* -+ * Test that a session cache overflow works as expected -+ * Test 0: TLSv1.3, timeout on new session later than old session -+ * Test 1: TLSv1.2, timeout on new session later than old session -+ * Test 2: TLSv1.3, timeout on new session earlier than old session -+ * Test 3: TLSv1.2, timeout on new session earlier than old session -+ */ -+#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) -+static int test_session_cache_overflow(int idx) -+{ -+ SSL_CTX *sctx = NULL, *cctx = NULL; -+ SSL *serverssl = NULL, *clientssl = NULL; -+ int testresult = 0; -+ SSL_SESSION *sess = NULL; -+ -+#ifdef OSSL_NO_USABLE_TLS1_3 -+ /* If no TLSv1.3 available then do nothing in this case */ -+ if (idx % 2 == 0) -+ return TEST_skip("No TLSv1.3 available"); -+#endif -+#ifdef OPENSSL_NO_TLS1_2 -+ /* If no TLSv1.2 available then do nothing in this case */ -+ if (idx % 2 == 1) -+ return TEST_skip("No TLSv1.2 available"); -+#endif -+ -+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), -+ TLS_client_method(), TLS1_VERSION, -+ (idx % 2 == 0) ? TLS1_3_VERSION -+ : TLS1_2_VERSION, -+ &sctx, &cctx, cert, privkey)) -+ || !TEST_true(SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET))) -+ goto end; -+ -+ SSL_CTX_sess_set_get_cb(sctx, get_session_cb); -+ get_sess_val = NULL; -+ -+ SSL_CTX_sess_set_cache_size(sctx, 1); -+ -+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, -+ NULL, NULL))) -+ goto end; -+ -+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) -+ goto end; -+ -+ if (idx > 1) { -+ sess = SSL_get_session(serverssl); -+ if (!TEST_ptr(sess)) -+ goto end; -+ -+ /* -+ * Cause this session to have a longer timeout than the next session to -+ * be added. -+ */ -+ if (!TEST_true(SSL_SESSION_set_timeout(sess, LONG_MAX))) { -+ sess = NULL; -+ goto end; -+ } -+ sess = NULL; -+ } -+ -+ SSL_shutdown(serverssl); -+ SSL_shutdown(clientssl); -+ SSL_free(serverssl); -+ SSL_free(clientssl); -+ serverssl = clientssl = NULL; -+ -+ /* -+ * Session cache size is 1 and we already populated the cache with a session -+ * so the next connection should cause an overflow. -+ */ -+ -+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, -+ NULL, NULL))) -+ goto end; -+ -+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) -+ goto end; -+ -+ /* -+ * The session we just negotiated may have been already removed from the -+ * internal cache - but we will return it anyway from our external cache. -+ */ -+ get_sess_val = SSL_get_session(serverssl); -+ if (!TEST_ptr(get_sess_val)) -+ goto end; -+ sess = SSL_get1_session(clientssl); -+ if (!TEST_ptr(sess)) -+ goto end; -+ -+ SSL_shutdown(serverssl); -+ SSL_shutdown(clientssl); -+ SSL_free(serverssl); -+ SSL_free(clientssl); -+ serverssl = clientssl = NULL; -+ -+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, -+ NULL, NULL))) -+ goto end; -+ -+ if (!TEST_true(SSL_set_session(clientssl, sess))) -+ goto end; -+ -+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) -+ goto end; -+ -+ testresult = 1; -+ -+ end: -+ SSL_free(serverssl); -+ SSL_free(clientssl); -+ SSL_CTX_free(sctx); -+ SSL_CTX_free(cctx); -+ SSL_SESSION_free(sess); -+ -+ return testresult; -+} -+#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */ -+ - /* - * Test 0: Client sets servername and server acknowledges it (TLSv1.2) - * Test 1: Client sets servername and server does not acknowledge it (TLSv1.2) -@@ -10738,6 +10857,9 @@ int setup_tests(void) - ADD_TEST(test_set_verify_cert_store_ssl_ctx); - ADD_TEST(test_set_verify_cert_store_ssl); - ADD_ALL_TESTS(test_session_timeout, 1); -+#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) -+ ADD_ALL_TESTS(test_session_cache_overflow, 4); -+#endif - ADD_TEST(test_load_dhfile); - #if !defined(OPENSSL_NO_TLS1_2) && !defined(OSSL_NO_USABLE_TLS1_3) - ADD_ALL_TESTS(test_serverinfo_custom, 4); --- -2.33.0 - diff --git a/0045-Limit-the-execution-time-of-RSA-public-key-check.patch b/0045-Limit-the-execution-time-of-RSA-public-key-check.patch deleted file mode 100644 index f68f6dff4b54b5497675e22e8462b5a5826e73ea..0000000000000000000000000000000000000000 --- a/0045-Limit-the-execution-time-of-RSA-public-key-check.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 02ec2aa154d26f078e9457998cd2e64b05b35b53 Mon Sep 17 00:00:00 2001 -From: Tomas Mraz -Date: Fri, 22 Dec 2023 16:25:56 +0100 -Subject: [PATCH] Limit the execution time of RSA public key check - -Fixes CVE-2023-6237 - -If a large and incorrect RSA public key is checked with -EVP_PKEY_public_check() the computation could take very long time -due to no limit being applied to the RSA public key size and -unnecessarily high number of Miller-Rabin algorithm rounds -used for non-primality check of the modulus. - -Now the keys larger than 16384 bits (OPENSSL_RSA_MAX_MODULUS_BITS) -will fail the check with RSA_R_MODULUS_TOO_LARGE error reason. -Also the number of Miller-Rabin rounds was set to 5. - -Reviewed-by: Neil Horman -Reviewed-by: Matt Caswell -(Merged from https://github.com/openssl/openssl/pull/23243) - -reference: https://github.com/openssl/openssl/pull/23243 -Signed-off-by: ShenYage ---- - .../openssl/crypto/rsa/rsa_sp800_56b_check.c | 8 +++- - .../openssl/test/recipes/91-test_pkey_check.t | 2 +- - .../91-test_pkey_check_data/rsapub_17k.pem | 48 +++++++++++++++++++ - 3 files changed, 56 insertions(+), 2 deletions(-) - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c -index fc8f19b..bcbdd24 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c -@@ -289,6 +289,11 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa) - return 0; - - nbits = BN_num_bits(rsa->n); -+ if (nbits > OPENSSL_RSA_MAX_MODULUS_BITS) { -+ ERR_raise(ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE); -+ return 0; -+ } -+ - #ifdef FIPS_MODULE - /* - * (Step a): modulus must be 2048 or 3072 (caveat from SP800-56Br1) -@@ -324,7 +329,8 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa) - goto err; - } - -- ret = ossl_bn_miller_rabin_is_prime(rsa->n, 0, ctx, NULL, 1, &status); -+ /* Highest number of MR rounds from FIPS 186-5 Section B.3 Table B.1 */ -+ ret = ossl_bn_miller_rabin_is_prime(rsa->n, 5, ctx, NULL, 1, &status); - #ifdef FIPS_MODULE - if (ret != 1 || status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME) { - #else -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t -index dc7cc64..f8088df 100644 ---- a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t -@@ -70,7 +70,7 @@ push(@positive_tests, ( - "dhpkey.pem" - )) unless disabled("dh"); - --my @negative_pubtests = (); -+my @negative_pubtests = ("rsapub_17k.pem"); # Too big RSA public key - - push(@negative_pubtests, ( - "dsapub_noparam.der" -diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem -new file mode 100644 -index 0000000..9a2eaed ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem -@@ -0,0 +1,48 @@ -+-----BEGIN PUBLIC KEY----- -+MIIIbzANBgkqhkiG9w0BAQEFAAOCCFwAMIIIVwKCCE4Ang+cE5H+hg3RbapDAHqR -+B9lUnp2MlAwsZxQ/FhYepaR60bFQeumbu7817Eo5YLMObVI99hF1C4u/qcpD4Jph -+gZt87/JAYDbP+DIh/5gUXCL9m5Fp4u7mvZaZdnlcftBvR1uKUTCAwc9pZ/Cfr8W2 -+GzrRODzsNYnk2DcZMfe2vRDuDZRopE+Y+I72rom2SZLxoN547N1daM/M/CL9KVQ/ -+XMI/YOpJrBI0jI3brMRhLkvLckwies9joufydlGbJkeil9H7/grj3fQZtFkZ2Pkj -+b87XDzRVX7wsEpAgPJxskL3jApokCp1kQYKG+Uc3dKM9Ade6IAPK7VKcmbAQTYw2 -+gZxsc28dtstazmfGz0ACCTSMrmbgWAM3oPL7RRzhrXDWgmYQ0jHefGh8SNTIgtPq -+TuHxPYkDMQNaf0LmDGCxqlnf4b5ld3YaU8zZ/RqIRx5v/+w0rJUvU53qY1bYSnL1 -+vbqKSnN2mip0GYyQ4AUgkS1NBV4rGYU/VTvzEjLfkg02KOtHKandvEoUjmZPzCT0 -+V2ZhGc8K1UJNGYlIiHqCdwCBoghvly/pYajTkDXyd6BsukzA5H3IkZB1xDgl035j -+/0Cr7QeZLEOdi9fPdSSaBT6OmD0WFuZfJF0wMr7ucRhWzPXvSensD9v7MBE7tNfH -+SLeTSx8tLt8UeWriiM+0CnkPR1IOqMOxubOyf1eV8NQqEWm5wEQG/0IskbOKnaHa -+PqLFJZn/bvyL3XK5OxVIJG3z6bnRDOMS9SzkjqgPdIO8tkySEHVSi/6iuGUltx3Y -+Fmq6ye/r34ekyHPbfn6UuTON7joM6SIXb5bHM64x4iMVWx4hMvDjfy0UqfywAUyu -+C1o7BExSMxxFG8GJcqR0K8akpPp7EM588PC+YuItoxzXgfUJnP3BQ1Beev2Ve7/J -+xeGZH0N4ntfr+cuaLAakAER9zDglwChWflw3NNFgIdAgSxXv3XXx5xDXpdP4lxUo -+F5zAN4Mero3yV90FaJl7Vhq/UFVidbwFc15jUDwaE0mKRcsBeVd3GOhoECAgE0id -+aIPT20z8oVY0FyTJlRk7QSjo8WjJSrHY/Fn14gctX07ZdfkufyL6w+NijBdYluvB -+nIrgHEvpkDEWoIa8qcx0EppoIcmqgMV2mTShfFYSybsO33Pm8WXec2FXjwhzs1Pi -+R/BuIW8rHPI67xqWm0h8dEw11vtfi9a/BBBikFHe59KBjMTG+lW/gADNvRoTzGh7 -+kN4+UVDS3jlSisRZZOn1XoeQtpubNYWgUsecjKy45IwIj8h1SHgn3wkmUesY0woN -+mOdoNtq+NezN4RFtbCOHhxFVpKKDi/HQP2ro0ykkXMDjwEIVf2Lii1Mg9UP8m+Ux -+AOqkTrIkdogkRx+70h7/wUOfDIFUq2JbKzqxJYamyEphcdAko7/B8efQKc61Z93O -+f2SHa4++4WI7wIIx18v5KV4M/cRmrfc8w9WRkQN3gBT5AJMuqwcSHVXBWvNQeGmi -+ScMh7X6cCZ0daEujqb8svq4WgsJ8UT4GaGBRIYtt7QUKEh+JQwNJzneRYZ3pzpaH -+UJeeoYobMlkp3rM9cYzdq90nBQiI9Jsbim9m9ggb2dMOS5CsI9S/IuG2O5uTjfxx -+wkwsd5nLDFtNXHYZ7W6XlVJ1Rc6zShnEmdCn3mmibb6OaMUmun2yl9ryEjVSoXLP -+fSA8W9K9yNhKTRkzdXJfqlC+s/ovX2xBGxsuOoUDaXhRVz0qmpKIHeSFjIP4iXq4 -+y8gDiwvM3HbZfvVonbg6siPwpn4uvw3hesojk1DKAENS52i6U3uK2fs1ALVxsFNS -+Yh914rDu0Q3e4RXVhURaYzoEbLCot6WGYeCCfQOK0rkETMv+sTYYscC8/THuW7SL -+HG5zy9Ed95N1Xmf8J+My7gM7ZFodGdHsWvdzEmqsdOFh6IVx/VfHFX0MDBq0t6lZ -+eRvVgVCfu3gkYLwPScn/04E02vOom51ISKHsF/I11erC66jjNYV9BSpH8O7sAHxZ -+EmPT2ZVVRSgivOHdQW/FZ3UZQQhVaVSympo2Eb4yWEMFn84Q8T+9Honj6gnB5PXz -+chmeCsOMlcg1mwWwhn0k+OAWEZy7VRUk5Ahp0fBAGJgwBdqrZ3kM356DjUkVBiYq -+4eHyvafNKmjf2mnFsI3g2NKRNyl1Lh63wyCFx60yYvBUfXF/W9PFJbD9CiP83kEW -+gV36gxTsbOSfhpO1OXR90ODy0kx06XzWmJCUugK8u9bx4F/CjV+LIHExuNJiethC -+A8sIup/MT0fWp4RO/SsVblGqfoqJTaPnhptQzeH2N07pbWkxeMuL6ppPuwFmfVjK -+FJndqCVrAukcPEOQ16iVURuloJMudqYRc9QKkJFsnv0W/iMNbqQGmXe8Q/5qFiys -+26NIQBiE2ad9hNLnoccEnmYSRgnW3ZPSKuq5TDdYyDqTZH2r8cam65pr3beKw2XC -+xw4cc7VaxiwGC2Mg2wRmwwPaTjrcEt6sMa3RjwFEVBxBFyM26wnTEZsTBquCxV0J -+pgERaeplkixP2Q0m7XAdlDaob973SM2vOoUgypzDchWmpx7u775bnOfU5CihwXl+ -+k0i09WZuT8bPmhEAiGCw5sNzMkz1BC2cCZFfJIkE2vc/wXYOrGxBTJo0EKaUFswa -+2dnP/u0bn+VksBUM7ywW9LJSXh4mN+tpzdeJtxEObKwX1I0dQxSPWmjd2++wMr9q -+Unre5fCrDToy2H7C2VKSpuOCT2/Kv4JDQRWwI4KxQOpn0UknAGNmfBoTtpIZ3LEb -+77oBUJdMQD7tQBBLL0a6f1TdK0dHVprWWawJ+gGFMiMQXqAqblHcxFKWuHv9bQID -+AQAB -+-----END PUBLIC KEY----- --- -2.33.0 - diff --git a/brotli-gitf4153a0.tar.gz b/brotli-gitf4153a0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e252ff46bcbe34cd17d2d4ba6cea479a59792604 Binary files /dev/null and b/brotli-gitf4153a0.tar.gz differ diff --git a/brotli.f4153a09f87cbb9c826d8fc12c74642bb2d879ea.tar.gz b/brotli.f4153a09f87cbb9c826d8fc12c74642bb2d879ea.tar.gz deleted file mode 100644 index 6a83abbf90052dfe266dc39b6f6fd61b8c9247f9..0000000000000000000000000000000000000000 Binary files a/brotli.f4153a09f87cbb9c826d8fc12c74642bb2d879ea.tar.gz and /dev/null differ diff --git a/edk2-loongarch64.json b/edk2-loongarch64.json new file mode 100644 index 0000000000000000000000000000000000000000..1108f8f5409029c1299982ca402101c1560679ab --- /dev/null +++ b/edk2-loongarch64.json @@ -0,0 +1,31 @@ +{ + "description": "UEFI firmware for LoongArch64 virtual machines", + "interface-types": [ + "uefi" + ], + "mapping": { + "device": "flash", + "executable": { + "filename": "/usr/share/edk2/loongarch64/QEMU_EFI-silent-pflash.raw", + "format": "raw" + }, + "nvram-template": { + "filename": "/usr/share/edk2/loongarch64/vars-template-pflash.raw", + "format": "raw" + } + }, + "targets": [ + { + "architecture": "loongarch64", + "machines": [ + "virt*" + ] + } + ], + "features": [ + + ], + "tags": [ + + ] +} diff --git a/edk2-platforms-7f42d4034c8f.tar.xz b/edk2-platforms-7f42d4034c8f.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..75212941f914a44f3b3104085740efc963937816 Binary files /dev/null and b/edk2-platforms-7f42d4034c8f.tar.xz differ diff --git a/edk2-stable202308.tar.gz b/edk2-stable202402.tar.gz similarity index 65% rename from edk2-stable202308.tar.gz rename to edk2-stable202402.tar.gz index b3d17c18b34ff35d3b934ddcb79047e026a6127a..07ca4d6cb44cf9282ddb0aea91ce2838987e2ba9 100644 Binary files a/edk2-stable202308.tar.gz and b/edk2-stable202402.tar.gz differ diff --git a/edk2.spec b/edk2.spec index 6a4b577e73d820e28184db5edaac2ac705448621..9fc34dfcfdecd211819eb0fa8d404b2098ebc26c 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,73 +1,29 @@ -%global stable_date 202308 +%global stable_date 202402 %global release_tag edk2-stable%{stable_date} -%global openssl_commitid de90e54bbe82e5be4fb9608b6f5c308bb837d355 -%global brotli_commitid f4153a09f87cbb9c826d8fc12c74642bb2d879ea +%define OPENSSL_VER 3.0.12 +%global softfloat_version 20180726-gitb64af41 %global public_mipi_sys_t_commitid 370b5944c046bab043dd8b133727b2135af7747a %global _python_bytecompile_extra 0 Name: edk2 Version: %{stable_date} -Release: 7 +Release: 1 Summary: EFI Development Kit II License: BSD-2-Clause-Patent and OpenSSL and MIT URL: https://github.com/tianocore/edk2 -Source0: https://github.com/tianocore/edk2/archive/%{release_tag}.tar.gz -Source1: openssl.%{openssl_commitid}.tar.gz -Source2: brotli.%{brotli_commitid}.tar.gz + +Source0: https://github.com/tianocore/edk2/archive/refs/tags/%{release_tag}.tar.gz +Source1: openssl-%{OPENSSL_VER}.tar.gz +# https://github.com/google/brotli/tree/f4153a09f87cbb9c826d8fc12c74642bb2d879ea +Source2: brotli-gitf4153a0.tar.gz Source3: public-mipi-sys-t.%{public_mipi_sys_t_commitid}.tar.gz -Source4: edk2-aarch64-verbose-raw.json -Source5: edk2-ovmf-x64-nosb.json - -patch0: 0001-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch -patch1: 0002-add-Wno-maybe-uninitialized-to-fix-build-error.patch -patch2: 0003-Add-testcases-for-empty-associated-data-entries-with.patch -patch3: 0004-Do-not-ignore-empty-associated-data-with-AES-SIV-mod.patch -patch4: 0005-Add-a-test-for-CVE-2023-3446.patch -patch5: 0006-Fix-DH_check-excessive-time-with-over-sized-modulus.patch -patch6: 0007-Make-DH_check-set-some-error-bits-in-recently-added-.patch -patch7: 0008-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch -patch8: 0009-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch -patch9: 0010-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch -patch10: 0011-poly1305-ppc.pl-Fix-vector-register-clobbering.patch -patch11: 0012-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch -patch12: 0013-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch -patch13: 0014-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch -patch14: 0015-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch -patch15: 0016-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch -patch16: 0017-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch -patch17: 0018-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch -patch18: 0019-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch -patch19: 0020-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch -patch20: 0021-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch - -# Fix CVE-2023-45229、CVE-2023-45230、CVE-2023-45231、CVE-2023-45232、CVE-2023-45233、CVE-2023-45234、CVE-2023-45235 -patch21: 0021-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Pa.patch -patch22: 0022-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch -patch23: 0023-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch -patch24: 0024-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch -patch25: 0025-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch -patch26: 0026-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch -patch27: 0027-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch -patch28: 0028-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch -patch29: 0029-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch -patch30: 0030-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch -patch31: 0031-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch -patch32: 0032-MdePkg-Test-Add-gRT_GetTime-Google-Test-Mock.patch -patch33: 0033-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch -patch34: 0034-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch -patch35: 0035-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch -patch36: 0036-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch -patch37: 0037-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch -patch38: 0038-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch -patch39: 0039-NetworkPkg-Updating-SecurityFixes.yaml.patch - -# Fix CVE-2023-6237、CVE-2024-2511 -patch40: 0040-Add-a-test-for-session-cache-handling.patch -patch41: 0041-Extend-the-multi_resume-test-for-simultaneous-resump.patch -patch42: 0042-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch -patch43: 0043-Hardening-around-not_resumable-sessions.patch -patch44: 0044-Add-a-test-for-session-cache-overflow.patch -patch45: 0045-Limit-the-execution-time-of-RSA-public-key-check.patch +Source5: https://github.com/akheron/jansson/releases/download/v2.13.1/jansson-2.13.1.tar.bz2 +# https://github.com/tianocore/edk2-platforms/commit/54306d023e7d610d326d103852bc6a45c803012e +Source6: edk2-platforms-7f42d4034c8f.tar.xz + +Source11: edk2-aarch64-verbose-raw.json +Source12: edk2-ovmf-x64-nosb.json +Source13: edk2-loongarch64.json BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl @@ -124,16 +80,30 @@ BuildArch: noarch EFI Development Kit II Open Virtual Machine Firmware (riscv64) %endif +%ifarch loongarch64 +%package ovmf-loongarch64 +Summary: Open Virtual Machine Firmware +BuildArch: noarch +%description ovmf-loongarch64 +EFI Development Kit II Open Virtual Machine Firmware (loongarch64) +%endif + %prep %setup -n edk2-%{release_tag} tar -xf %{SOURCE1} -C CryptoPkg/Library/OpensslLib/openssl --strip-components=1 tar -xf %{SOURCE2} -C MdeModulePkg/Library/BrotliCustomDecompressLib/brotli --strip-components=1 tar -xf %{SOURCE2} -C BaseTools/Source/C/BrotliCompress/brotli --strip-components=1 +tar -xf %{SOURCE5} -C RedfishPkg/Library/JsonLib/jansson --strip-components=1 tar -xf %{SOURCE3} -C MdePkg/Library/MipiSysTLib/mipisyst --strip-components=1 +tar -xf %{SOURCE6} edk2-platforms-7f42d4034c8f/Platform --strip-components=1 +# include paths pointing to unused submodules +#mkdir -p CryptoPkg/Library/MbedTlsLib/mbedtls/include +#mkdir -p CryptoPkg/Library/MbedTlsLib/mbedtls/include/mbedtls +#mkdir -p CryptoPkg/Library/MbedTlsLib/mbedtls/library %autopatch -p1 -cp -a -- %{SOURCE4} %{SOURCE5} . +cp -a -- %{SOURCE11} %{SOURCE12} %{SOURCE13} . %build NCPUS=`/usr/bin/getconf _NPROCESSORS_ONLN` @@ -166,6 +136,10 @@ BUILD_OPTION="$BUILD_OPTION -D TPM_CONFIG_ENABLE=TRUE" BUILD_OPTION="-t GCC5 -n $NCPUS -b RELEASE -a RISCV64 -p OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc -D SECURE_BOOT_ENABLE=TRUE -D TPM_ENABLE=TRUE -D TPM_CONFIG_ENABLE=TRUE" %endif +%ifarch loongarch64 + BUILD_OPTION="-t GCC5 -n $NCPUS -b RELEASE -a LOONGARCH64 -p Platform/Loongson/LoongArchQemuPkg/Loongson.dsc -D SECURE_BOOT_ENABLE=TRUE -D TPM_ENABLE=TRUE -D TPM_CONFIG_ENABLE=TRUE" +%endif + build $BUILD_OPTION %install @@ -230,6 +204,15 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys cp Build/RiscVVirtQemu/RELEASE_GCC5/FV/RISCV_VIRT_VARS.fd %{buildroot}/usr/share/%{name}/ovmf-riscv64 %endif +%ifarch loongarch64 + mkdir -p %{buildroot}/usr/share/%{name}/loongarch64 + cp Build/LoongArchQemu/RELEASE_*/FV/*.fd %{buildroot}/usr/share/%{name}/loongarch64 + dd of="%{buildroot}/usr/share/%{name}/loongarch64/QEMU_EFI-silent-pflash.raw" if="/dev/zero" bs=1M count=4 + dd of="%{buildroot}/usr/share/%{name}/loongarch64/QEMU_EFI-silent-pflash.raw" if="%{buildroot}/usr/share/%{name}/loongarch64/QEMU_EFI.fd" conv=notrunc + dd of="%{buildroot}/usr/share/%{name}/loongarch64/vars-template-pflash.raw" if="/dev/zero" bs=1M count=16 + install -m 0644 edk2-loongarch64.json %{buildroot}%{_datadir}/qemu/firmware/50-edk2-loongarch64.json +%endif + %files devel %license License.txt %license License-History.txt @@ -306,7 +289,19 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys %{_datadir}/%{name}/ovmf-riscv64 %endif +%ifarch loongarch64 +%license OvmfPkg/License.txt +%license LICENSE.openssl +%files ovmf-loongarch64 +%dir %{_datadir}/%{name} +%{_datadir}/%{name}/loongarch64 +%{_datadir}/qemu/firmware/50-edk2-loongarch64.json +%endif + %changelog +* Sat Jun 1 2024 Xiaotian Wu - 202402-1 +- add LoongArch support + * Wed Apr 17 2024 jiangdongxu - 202308-7 - make EFI_LOADER_DATA executable again. diff --git a/jansson-2.13.1.tar.bz2 b/jansson-2.13.1.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..48d750663db027ab5fdd9dd980b948a47ee4d344 Binary files /dev/null and b/jansson-2.13.1.tar.bz2 differ diff --git a/openssl.de90e54bbe82e5be4fb9608b6f5c308bb837d355.tar.gz b/openssl-3.0.12.tar.gz similarity index 63% rename from openssl.de90e54bbe82e5be4fb9608b6f5c308bb837d355.tar.gz rename to openssl-3.0.12.tar.gz index dd3e1788aba370f6ce283c967aa7c4087c6a4a67..4fb7c5f6e5f63dc609156763733126550081dd7e 100644 Binary files a/openssl.de90e54bbe82e5be4fb9608b6f5c308bb837d355.tar.gz and b/openssl-3.0.12.tar.gz differ