fix CVE-2023-40547 CVE-2023-40548 CVE-2023-40549 CVE-2023-40550 CVE-2023-40551

This commit is contained in:
jinlun 2024-01-25 10:28:55 +08:00
parent 1a2bd82fa5
commit 387de7595c
10 changed files with 612 additions and 1 deletions

View File

@ -0,0 +1,51 @@
From f27182695d88350b48c8b9a6dce54bb513d7aa4e Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 27 Jul 2023 15:13:08 -0400
Subject: [PATCH] Add primitives for overflow-checked arithmetic operations.
We need to do arithmetic on untrusted values sometimes, so this patch
adds the following primitives as macros that wrap the compiler builtins.
bool checked_add(TYPE addend0, TYPE addend1, TYPE *sum)
bool checked_sub(TYPE minuend, TYPE subtrahend, TYPE *difference)
bool checked_mul(TYPE factor0, TYPE factor1, TYPE *product)
And also the following primitive which returns True if divisor is 0 and
False otherwise:
bool checked_div(TYPE dividend, TYPE divisor, TYPE *quotient)
Signed-off-by: Peter Jones <pjones@redhat.com>
---
include/compiler.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/include/compiler.h b/include/compiler.h
index b0d595f..545a72e 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -198,5 +198,21 @@
#error shim has no cache_invalidate() implementation for this compiler
#endif /* __GNUC__ */
+#define checked_add(addend0, addend1, sum) \
+ __builtin_add_overflow(addend0, addend1, sum)
+#define checked_sub(minuend, subtrahend, difference) \
+ __builtin_sub_overflow(minuend, subtrahend, difference)
+#define checked_mul(factor0, factor1, product) \
+ __builtin_mul_overflow(factor0, factor1, product)
+#define checked_div(dividend, divisor, quotient) \
+ ({ \
+ bool _ret = True; \
+ if ((divisor) != 0) { \
+ _ret = False; \
+ (quotient) = (dividend) / (divisor); \
+ } \
+ _ret; \
+ })
+
#endif /* !COMPILER_H_ */
// vim:fenc=utf-8:tw=75:et
--
2.33.0

View File

@ -0,0 +1,45 @@
From 0226b56513b2b8bd5fd281bce77c40c9bf07c66d Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 2 Aug 2023 14:19:31 -0400
Subject: [PATCH] CVE-2023-40547 - avoid incorrectly trusting HTTP headers
When retrieving files via HTTP or related protocols, shim attempts to
allocate a buffer to store the received data. Unfortunately, this means
getting the size from an HTTP header, which can be manipulated to
specify a size that's smaller than the received data. In this case, the
code accidentally uses the header for the allocation but the protocol
metadata to copy it from the rx buffer, resulting in an out-of-bounds
write.
This patch adds an additional check to test that the rx buffer is not
larger than the allocation.
Resolves: CVE-2023-40547
Reported-by: Bill Demirkapi, Microsoft Security Response Center
Signed-off-by: Peter Jones <pjones@redhat.com>
---
httpboot.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/httpboot.c b/httpboot.c
index dfa493b..b34dd49 100644
--- a/httpboot.c
+++ b/httpboot.c
@@ -578,7 +578,13 @@ receive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINT64 *buf_size)
}
if (*buf_size == 0) {
- perror(L"Failed to get Content-Lenght\n");
+ perror(L"Failed to get Content-Length\n");
+ goto error;
+ }
+
+ if (*buf_size < rx_message.BodyLength) {
+ efi_status = EFI_BAD_BUFFER_SIZE;
+ perror(L"Invalid Content-Length\n");
goto error;
}
--
2.33.0

View File

@ -0,0 +1,75 @@
From 96dccc255b16e9465dbee50b3cef6b3db74d11c8 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 27 Jul 2023 15:21:31 -0400
Subject: [PATCH] CVE-2023-40548 Fix integer overflow on SBAT section size on
32-bit system
In verify_sbat_section(), we do some math on data that comes from the
binary being verified - in this case, we add 1 to the size of the
".sbat" section as reported in the section header, which is then used as
the input to the size of an allocation. The original value is then used
for a size in a memcpy(), which means there's an out-of-bounds write in
the overflow case.
Due to the type of the variable being size_t, but the type in the
section header being uint32_t, this is only plausibly accomplished on
32-bit systems.
This patch makes the arithmetic use a checked add operation to avoid
overflow. Additionally, it adds a check in verify_buffer_sbat() to
guarantee that the data is within the binary.
It's not currently known if this is actually exploitable on such
systems; the memory layout on a particular machine may further mitigate
this scenario.
Resolves: CVE-2023-40548
Reported-by: gkirkpatrick@google.com
Signed-off-by: Peter Jones <pjones@redhat.com>
---
pe.c | 6 +++++-
shim.c | 6 ++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/pe.c b/pe.c
index e15b89f..b3a9d46 100644
--- a/pe.c
+++ b/pe.c
@@ -355,7 +355,11 @@ verify_sbat_section(char *SBATBase, size_t SBATSize)
return in_protocol ? EFI_SUCCESS : EFI_SECURITY_VIOLATION;
}
- sbat_size = SBATSize + 1;
+ if (checked_add(SBATSize, 1, &sbat_size)) {
+ dprint(L"SBATSize + 1 would overflow\n");
+ return EFI_SECURITY_VIOLATION;
+ }
+
sbat_data = AllocatePool(sbat_size);
if (!sbat_data) {
console_print(L"Failed to allocate .sbat section buffer\n");
diff --git a/shim.c b/shim.c
index 3fd1e2a..84a98ca 100644
--- a/shim.c
+++ b/shim.c
@@ -743,11 +743,17 @@ verify_buffer_sbat (char *data, int datasize,
* and ignore the section if it isn't. */
if (Section->SizeOfRawData &&
Section->SizeOfRawData >= Section->Misc.VirtualSize) {
+ uint64_t boundary;
SBATBase = ImageAddress(data, datasize,
Section->PointerToRawData);
SBATSize = Section->SizeOfRawData;
dprint(L"sbat section base:0x%lx size:0x%lx\n",
SBATBase, SBATSize);
+ if (checked_add((uint64_t)SBATBase, SBATSize, &boundary) ||
+ (boundary > (uint64_t)data + datasize)) {
+ perror(L"Section exceeds bounds of image\n");
+ return EFI_UNSUPPORTED;
+ }
}
}
--
2.33.0

View File

@ -0,0 +1,62 @@
From afdc5039de0a4a3a40162a32daa070f94a883f09 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 27 Jul 2023 14:58:55 -0400
Subject: [PATCH] CVE-2023-40549 Authenticode: verify that the signature header
is in bounds.
In the validation logic in verify_buffer_authenticode(), there is yet
another case where we need to guarantee an object is in the binary but
we're only validating the pointer to it. In this case, we're validating
that the actual signature data is in the binary, but unfortunately we
failed to validate that the header describing it is, so a malformed
binary can cause us to take an out-of-bounds read (probably but not
necessarily on the same page) past the end of the buffer.
This patch adds a bounds check to verify that the signature is
actually within the bounds.
It seems unlikely this can be used for more than a denial of service,
and if you can get shim to try to verify a malformed binary, you've
effectively already accomplished a DoS.
Resolves: CVE-2023-40549
Reported-by: gkirkpatrick@google.com
Signed-off-by: Peter Jones <pjones@redhat.com>
---
shim.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/shim.c b/shim.c
index 3a97067..3fd1e2a 100644
--- a/shim.c
+++ b/shim.c
@@ -627,11 +627,13 @@ verify_buffer_authenticode (char *data, int datasize,
return EFI_SECURITY_VIOLATION;
}
- if (context->SecDir->Size >= size) {
+ if (checked_add(context->SecDir->Size, context->SecDir->VirtualAddress, &offset) ||
+ offset > size) {
perror(L"Certificate Database size is too large\n");
return EFI_INVALID_PARAMETER;
}
+ offset = 0;
ret_efi_status = EFI_NOT_FOUND;
do {
WIN_CERTIFICATE_EFI_PKCS *sig = NULL;
@@ -642,6 +644,11 @@ verify_buffer_authenticode (char *data, int datasize,
if (!sig)
break;
+ if ((uint64_t)&sig[1] > (uint64_t)data + datasize) {
+ perror(L"Certificate size is too large for secruity database");
+ return EFI_INVALID_PARAMETER;
+ }
+
sz = offset + offsetof(WIN_CERTIFICATE_EFI_PKCS, Hdr.dwLength)
+ sizeof(sig->Hdr.dwLength);
if (sz > context->SecDir->Size) {
--
2.33.0

View File

@ -0,0 +1,47 @@
From 93ce2552f3e9f71f888a672913bfc0eef255c56d Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 27 Jul 2023 14:57:32 -0400
Subject: [PATCH] CVE-2023-40550 pe: Fix an out-of-bound read in
verify_buffer_sbat()
In verify_buffer_sbat(), we have a goal-seeking loop to find the .sbat
section header. Unfortunately, while the actual contents of the section
are checked for being inside the binary, no such check exists for the
contents of the section table entry.
As a result, a carefully constructed binary will cause an out-of-bounds
read checking if the section name is ".sbat\0\0\0" or not.
This patch adds a check that each section table entry is within the
bounds of the binary.
It's not currently known if this is actually exploitable beyond creating
a denial of service, and an attacker who is in a position to use it for
a denial of service attack must already be able to do so.
Resolves: CVE-2023-40550
Reported-by: gkirkpatrick@google.com
Signed-off-by: Peter Jones <pjones@redhat.com>
---
shim.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/shim.c b/shim.c
index 01e5e56..3a97067 100644
--- a/shim.c
+++ b/shim.c
@@ -709,6 +709,11 @@ verify_buffer_sbat (char *data, int datasize,
Section = context->FirstSection;
for (i = 0; i < context->NumberOfSections; i++, Section++) {
+ if ((uint64_t)&Section[1] > (uint64_t)data + datasize) {
+ perror(L"Section exceeds bounds of image\n");
+ return EFI_UNSUPPORTED;
+ }
+
if (CompareMem(Section->Name, ".sbat\0\0\0", 8) != 0)
continue;
--
2.33.0

View File

@ -0,0 +1,86 @@
From f93d9d8c546eed520314ce435c26b184663e1032 Mon Sep 17 00:00:00 2001
From: jinlun <jinlun@huawei.com>
Date: Thu, 25 Jan 2024 14:50:03 +0800
Subject: [PATCH] CVE-2023-40551: pe-relocate: Fix bounds check for MZ binaries
In read_header(), we attempt to parse the PE binary headers. In doing
so, if there is an MZ (i.e. MS-DOS) header, we locate the PE header by
finding the offset in that header. Unfortunately that is not correctly
bounds checked, and carefully chosen values can cause an out-of-bounds
ready beyond the end of the loaded binary.
Unfortunately the trivial fix (bounds check that value) also makes it
clear that the way we were determining if an image is loadable on this
platform and distinguishing between PE32 and PE32+ binaries has the
exact same issue going on, and so the fix includes reworking that logic
to correctly bounds check all of those tests as well.
h
It's not currently known if this is actually exploitable beyond creating
a denial of service, and an attacker who is in a position to use it for
a denial of service attack must already be able to do so.
Resolves: CVE-2023-40551
Reported-by: gkirkpatrick@google.com
Signed-off-by: Peter Jones <pjones@redhat.com>
---
pe.c | 24 ++++++++++++++++++++++--
post-process-pe.c | 2 +-
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/pe.c b/pe.c
index 96f9c0e..d14f2ff 100644
--- a/pe.c
+++ b/pe.c
@@ -771,14 +771,34 @@ read_header(void *data, unsigned int datasize,
unsigned long HeaderWithoutDataDir, SectionHeaderOffset, OptHeaderSize;
unsigned long FileAlignment = 0;
UINT16 DllFlags;
+ size_t dos_sz = 0;
- if (datasize < sizeof (PEHdr->Pe32)) {
+ if (datasize < sizeof (*DosHdr)) {
perror(L"Invalid image\n");
return EFI_UNSUPPORTED;
}
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE)
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ if (DosHdr->e_lfanew < sizeof (*DosHdr) ||
+ DosHdr->e_lfanew > datasize - 4) {
+ perror(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ dos_sz = DosHdr->e_lfanew;
PEHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((char *)data + DosHdr->e_lfanew);
+ }
+
+ if (datasize - dos_sz < sizeof (PEHdr->Pe32)) {
+ perror(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ if (image_is_64_bit(PEHdr) &&
+ (datasize - dos_sz < sizeof (PEHdr->Pe32Plus))) {
+ perror(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
if (!image_is_loadable(PEHdr)) {
perror(L"Platform does not support this image\n");
diff --git a/post-process-pe.c b/post-process-pe.c
index de8f4a3..86350ce 100644
--- a/post-process-pe.c
+++ b/post-process-pe.c
@@ -110,7 +110,7 @@ static int
image_is_64_bit(EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr)
{
/* .Magic is the same offset in all cases */
- if (PEHdr->Pe32Plus.OptionalHeader.Magic ==
+ if (PEHdr->Pe32.OptionalHeader.Magic ==
EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC)
return 1;
return 0;
--
2.33.0

View File

@ -0,0 +1,83 @@
From dae82f6bd72cf600e5d48046ec674a441d0f49d7 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 2 Aug 2023 14:36:09 -0400
Subject: [PATCH] Further mitigations against CVE-2023-40546 as a class
In CVE-2023-40546, an incorrect invocation of LogError()
causes a read from the page at address 0, which on newer systems will
correctly cause a fault. The immediate fix for this CVE is to fix the
invocation so that the error is logged correctly, but there is more that
can be done.
This patch adds additional checks to ensure that the format specifier on
any of these invocations can not be NULL, thereby mitigating this entire
class of error from creating a fault. Additionally, most of these
checks are done using _Static_assert(), so they should normally be
triggered at compile time.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
errlog.c | 3 +++
shim.h | 26 ++++++++++++++++++++------
2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/errlog.c b/errlog.c
index cc6a89f..3c5e0af 100644
--- a/errlog.c
+++ b/errlog.c
@@ -32,6 +32,9 @@ VLogError(const char *file, int line, const char *func, const CHAR16 *fmt,
ms_va_list args2;
CHAR16 **newerrs;
+ if (file == NULL || func == NULL || fmt == NULL)
+ return EFI_INVALID_PARAMETER;
+
newerrs = ReallocatePool(errs, (nerrs + 1) * sizeof(*errs),
(nerrs + 3) * sizeof(*errs));
if (!newerrs)
diff --git a/shim.h b/shim.h
index 3e221b5..652be45 100644
--- a/shim.h
+++ b/shim.h
@@ -281,18 +281,32 @@ verify_buffer (char *data, int datasize,
#ifndef SHIM_UNIT_TEST
#define perror_(file, line, func, fmt, ...) ({ \
UINTN __perror_ret = 0; \
+ _Static_assert((fmt) != NULL, \
+ "format specifier cannot be NULL"); \
if (!in_protocol) \
__perror_ret = console_print((fmt), ##__VA_ARGS__); \
LogError_(file, line, func, fmt, ##__VA_ARGS__); \
__perror_ret; \
})
-#define perror(fmt, ...) \
- perror_(__FILE__, __LINE__ - 1, __func__, fmt, ##__VA_ARGS__)
-#define LogError(fmt, ...) \
- LogError_(__FILE__, __LINE__ - 1, __func__, fmt, ##__VA_ARGS__)
+#define perror(fmt, ...) ({ \
+ _Static_assert((fmt) != NULL, \
+ "format specifier cannot be NULL"); \
+ perror_(__FILE__, __LINE__ - 1, __func__, fmt, ##__VA_ARGS__); \
+ })
+#define LogError(fmt, ...) ({ \
+ _Static_assert((fmt) != NULL, \
+ "format specifier cannot be NULL"); \
+ LogError_(__FILE__, __LINE__ - 1, __func__, fmt, ##__VA_ARGS__);\
+ })
#else
-#define perror(fmt, ...)
-#define LogError(fmt, ...)
+#define perror(fmt, ...) ({ \
+ _Static_assert((fmt) != NULL, \
+ "format specifier cannot be NULL"); \
+ })
+#define LogError(fmt, ...) ({ \
+ _Static_assert((fmt) != NULL, \
+ "format specifier cannot be NULL"); \
+ })
#endif
#ifdef ENABLE_SHIM_DEVEL
--
2.33.0

View File

@ -0,0 +1,37 @@
From e7f5fdf53ee68025f3ef2688e2f27ccb0082db83 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 27 Jul 2023 17:59:22 -0400
Subject: [PATCH] pe-relocate: Ensure nothing else implements CVE-2023-40550
In CVE-2023-40550, we scan the section headers for the section
name without having verified that the section header is actually in the
binary.
This patch adds such verification to read_headers()
Signed-off-by: Peter Jones <pjones@redhat.com>
---
pe-relocate.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/pe-relocate.c b/pe-relocate.c
index 1723642..cb7a02c 100644
--- a/pe.c
+++ b/pe.c
@@ -472,6 +472,13 @@ read_header(void *data, unsigned int datasize,
return EFI_UNSUPPORTED;
}
+ if (checked_mul((size_t)context->NumberOfSections, sizeof(EFI_IMAGE_SECTION_HEADER), &tmpsz0) ||
+ checked_add(tmpsz0, SectionHeaderOffset, &tmpsz0) ||
+ (tmpsz0 > datasize)) {
+ perror(L"Image sections overflow section headers\n");
+ return EFI_UNSUPPORTED;
+ }
+
if (checked_sub((size_t)(uintptr_t)PEHdr, (size_t)(uintptr_t)data, &tmpsz0) ||
checked_add(tmpsz0, sizeof(EFI_IMAGE_OPTIONAL_HEADER_UNION), &tmpsz0) ||
(tmpsz0 > datasize)) {
--
2.33.0

View File

@ -0,0 +1,112 @@
From e912071b8a6045549c2d1e7b5e1b2150c33ef519 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 26 Jul 2023 16:14:40 -0400
Subject: [PATCH] pe-relocate: make read_header() use checked arithmetic
operations.
Since the fuzzer already found one problem here, and none of that data
is intended to be trusted to begin with, it makes sense to use checked
math for all of the values read from the PE headers.
This updates all of that math to use checked arithmetic operations.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
pe-relocate.c | 49 +++++++++++++++++++++++++++++++++----------------
1 file changed, 33 insertions(+), 16 deletions(-)
diff --git a/pe-relocate.c b/pe-relocate.c
index b11fc68..1723642 100644
--- a/pe.c
+++ b/pe.c
@@ -376,6 +376,7 @@ read_header(void *data, unsigned int datasize,
unsigned long FileAlignment = 0;
UINT16 DllFlags;
size_t dos_sz = 0;
+ size_t tmpsz0, tmpsz1;
if (datasize < sizeof (*DosHdr)) {
perror(L"Invalid image\n");
@@ -443,31 +444,37 @@ read_header(void *data, unsigned int datasize,
return EFI_UNSUPPORTED;
}
- HeaderWithoutDataDir = OptHeaderSize
- - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
- if (((UINT32)PEHdr->Pe32.FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=
- context->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
+ if (checked_mul(sizeof(EFI_IMAGE_DATA_DIRECTORY), EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES, &tmpsz0) ||
+ checked_sub(OptHeaderSize, tmpsz0, &HeaderWithoutDataDir) ||
+ checked_sub((size_t)PEHdr->Pe32.FileHeader.SizeOfOptionalHeader, HeaderWithoutDataDir, &tmpsz0) ||
+ checked_mul((size_t)context->NumberOfRvaAndSizes, sizeof (EFI_IMAGE_DATA_DIRECTORY), &tmpsz1) ||
+ (tmpsz0 != tmpsz1)) {
perror(L"Image header overflows data directory\n");
return EFI_UNSUPPORTED;
}
- SectionHeaderOffset = DosHdr->e_lfanew
- + sizeof (UINT32)
- + sizeof (EFI_IMAGE_FILE_HEADER)
- + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader;
- if (((UINT32)context->ImageSize - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
- <= context->NumberOfSections) {
+ if (checked_add((size_t)DosHdr->e_lfanew, sizeof(UINT32), &tmpsz0) ||
+ checked_add(tmpsz0, sizeof(EFI_IMAGE_FILE_HEADER), &tmpsz0) ||
+ checked_add(tmpsz0, PEHdr->Pe32.FileHeader.SizeOfOptionalHeader, &SectionHeaderOffset)) {
perror(L"Image sections overflow image size\n");
return EFI_UNSUPPORTED;
}
- if ((context->SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
- < (UINT32)context->NumberOfSections) {
+ if (checked_sub((size_t)context->ImageSize, SectionHeaderOffset, &tmpsz0) ||
+ (tmpsz0 / EFI_IMAGE_SIZEOF_SECTION_HEADER <= context->NumberOfSections)) {
+ perror(L"Image sections overflow image size\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ if (checked_sub((size_t)context->SizeOfHeaders, SectionHeaderOffset, &tmpsz0) ||
+ (tmpsz0 / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)context->NumberOfSections)) {
perror(L"Image sections overflow section headers\n");
return EFI_UNSUPPORTED;
}
- if ((((UINT8 *)PEHdr - (UINT8 *)data) + sizeof(EFI_IMAGE_OPTIONAL_HEADER_UNION)) > datasize) {
+ if (checked_sub((size_t)(uintptr_t)PEHdr, (size_t)(uintptr_t)data, &tmpsz0) ||
+ checked_add(tmpsz0, sizeof(EFI_IMAGE_OPTIONAL_HEADER_UNION), &tmpsz0) ||
+ (tmpsz0 > datasize)) {
perror(L"Invalid image\n");
return EFI_UNSUPPORTED;
}
@@ -504,15 +511,25 @@ read_header(void *data, unsigned int datasize,
return EFI_UNSUPPORTED;
}
- context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)((char *)PEHdr + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader + sizeof(UINT32) + sizeof(EFI_IMAGE_FILE_HEADER));
+ if (checked_add((size_t)(uintptr_t)PEHdr, PEHdr->Pe32.FileHeader.SizeOfOptionalHeader, &tmpsz0) ||
+ checked_add(tmpsz0, sizeof(UINT32), &tmpsz0) ||
+ checked_add(tmpsz0, sizeof(EFI_IMAGE_FILE_HEADER), &tmpsz0)) {
+ perror(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
+ context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)(uintptr_t)tmpsz0;
+ if ((uint64_t)(context->FirstSection) > (uint64_t)data + datasize) {
+ perror(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
if (context->ImageSize < context->SizeOfHeaders) {
perror(L"Invalid image\n");
return EFI_UNSUPPORTED;
}
- if ((unsigned long)((UINT8 *)context->SecDir - (UINT8 *)data) >
- (datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) {
+ if (checked_sub((size_t)(uintptr_t)context->SecDir, (size_t)(uintptr_t)data, &tmpsz0) ||
+ (tmpsz0 > datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) {
perror(L"Invalid image\n");
return EFI_UNSUPPORTED;
}
--
2.33.0

View File

@ -25,7 +25,7 @@
Name: shim Name: shim
Version: 15.7 Version: 15.7
Release: 2 Release: 3
Summary: First-stage UEFI bootloader Summary: First-stage UEFI bootloader
ExclusiveArch: x86_64 aarch64 ExclusiveArch: x86_64 aarch64
License: BSD License: BSD
@ -35,6 +35,15 @@ Source1: BOOTAA64.CSV
Source2: BOOTX64.CSV Source2: BOOTX64.CSV
Patch1:backport-CVE-2023-40546.patch Patch1:backport-CVE-2023-40546.patch
Patch2:backport-CVE-2023-40551-pe-relocate-Fix-bounds-check-for-MZ-b.patch
Patch3:backport-pe-relocate-make-read_header-use-checked-arithmetic-.patch
Patch4:backport-Add-primitives-for-overflow-checked-arithmetic-opera.patch
Patch5:backport-CVE-2023-40550-pe-Fix-an-out-of-bound-read-in-verify.patch
Patch6:backport-pe-relocate-Ensure-nothing-else-implements-CVE-2023-40550.patch
Patch7:backport-CVE-2023-40548-Fix-integer-overflow-on-SBAT-section-.patch
Patch8:backport-CVE-2023-40547-avoid-incorrectly-trusting-HTTP-heade.patch
Patch9:backport-Further-mitigations-against-CVE-2023-40546-as-a-clas.patch
Patch10:backport-CVE-2023-40549-Authenticode-verify-that-the-signatur.patch
# Feature for shim SMx support # Feature for shim SMx support
Patch9000:Feature-shim-openssl-add-ec-support.patch Patch9000:Feature-shim-openssl-add-ec-support.patch
@ -156,6 +165,10 @@ make test
/usr/src/debug/%{name}-%{version}-%{release}/* /usr/src/debug/%{name}-%{version}-%{release}/*
%changelog %changelog
* Thu Jan 25 2024 jinlun <jinlun@huawei.com> - 15.7-3
- fix CVE-2023-40547 CVE-2023-40548 CVE-2023-40549 CVE-2023-40550
- CVE-2023-40551
* Tue Nov 7 2023 jinlun <jinlun@huawei.com> - 15.7-2 * Tue Nov 7 2023 jinlun <jinlun@huawei.com> - 15.7-2
- fix CVE-2023-40546 - fix CVE-2023-40546