Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
1ca2c7e0de
!182 同步代码,与22.03-LTS-SP3保持一致
From: @jinlun123123 
Reviewed-by: @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
2024-06-13 11:30:27 +00:00
jinlun
9f79b8e6cd Synchronize the code to be consistent with 22.03-LTS-SP3 2024-06-11 14:55:52 +08:00
openeuler-ci-bot
8063b52667
!157 【openEuler-22.03-LTS-Next】Backport patch from upstream
From: @yixiangzhike 
Reviewed-by: @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
2024-03-26 03:04:49 +00:00
yixiangzhike
6704d553cf Backport patch from upstream 2024-03-26 09:40:20 +08:00
openeuler-ci-bot
5eb41bed01
!144 fix CVE-2023-0465 CVE-2023-2650 CVE-2024-0727
From: @zhengxiaoxiaoGitee 
Reviewed-by: @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
2024-02-28 06:11:59 +00:00
zhengxiaoxiao
b08eeb318f fix CVE-2023-0465 CVE-2023-2650 CVE-2024-0727 2024-02-28 10:49:07 +08:00
openeuler-ci-bot
60eb19a199
!135 fix CVE-2023-40547 CVE-2023-40548 CVE-2023-40549 CVE-2023-40550 CVE-2023-40551
From: @zhengxiaoxiaoGitee 
Reviewed-by: @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
2024-01-31 01:17:27 +00:00
z30023234
a933f5375d fix CVE-2023-40547 CVE-2023-40548 CVE-2023-40549 CVE-2023-40550 CVE-2023-40551 2024-01-30 20:50:38 +08:00
openeuler-ci-bot
4cd034bf66
!122 backport patchs from upstream
From: @zhangruifang2020 
Reviewed-by: @huangzq6, @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
2024-01-02 11:51:23 +00:00
zhangruifang2020
29fc7c96d3 backport patchs from upstream 2023-12-25 17:19:55 +08:00
16 changed files with 1736 additions and 1 deletions

View File

@ -0,0 +1,706 @@
From 1dc5fe582bca752d2bafd6496132c63fa72b5e53 Mon Sep 17 00:00:00 2001
From: jinlun <jinlun@huawei.com>
Date: Tue, 21 Nov 2023 14:43:26 +0800
Subject: [PATCH] add tpcm support with ipmi channel
---
Makefile | 4 +-
shim.c | 13 +-
tpcm.c | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
tpcm.h | 202 ++++++++++++++++++++++++++
4 files changed, 644 insertions(+), 3 deletions(-)
create mode 100644 tpcm.c
create mode 100644 tpcm.h
diff --git a/Makefile b/Makefile
index 9b8d7e8..b619f78 100644
--- a/Makefile
+++ b/Makefile
@@ -41,9 +41,9 @@ endif
ifneq ($(origin ENABLE_SHIM_SM),undefined)
CFLAGS += -DENABLE_SHIM_SM
endif
-OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o pe.o httpboot.o csv.o load-options.o
+OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o pe.o httpboot.o csv.o load-options.o tpcm.o
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
-ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S
+ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S tpcm.h
MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o
ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h)
FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o
diff --git a/shim.c b/shim.c
index 400bd9a..c90c1a5 100644
--- a/shim.c
+++ b/shim.c
@@ -32,7 +32,7 @@
#include <Library/BaseCryptLib.h>
#include <stdint.h>
-
+#include "tpcm.h"
#define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2"
static EFI_SYSTEM_TABLE *systab;
@@ -1227,6 +1227,17 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
goto restore;
}
+ /*
+ * measure the grub binary by the tpcm
+ */
+ efi_status = tpcm_measure_grub(ImagePath, data, datasize, image_handle);
+ if (EFI_ERROR(efi_status)) {
+ perror(L"Failed to measure the grub by tpcm: %r\n", efi_status);
+ PrintErrors();
+ ClearErrors();
+ goto restore;
+ }
+
/*
* Verify and, if appropriate, relocate and execute the executable
*/
diff --git a/tpcm.c b/tpcm.c
new file mode 100644
index 0000000..42fcc2f
--- /dev/null
+++ b/tpcm.c
@@ -0,0 +1,428 @@
+/*
+ tpcm -- The main function file that implements the tpcm measurement.
+*/
+
+#include "tpcm.h"
+#include "shim.h"
+
+#define TRANS(value) \
+ ((((UINT32)(value) << 24) & 0xFF000000) | (((UINT32)(value) << 8) & 0x00FF0000) | \
+ (((UINT32)(value) >> 8) & 0x0000FF00) | (((UINT32)(value) >> 24) & 0x000000FF))
+
+#define WAIT_TIME_UNIT 200
+
+static EFI_GUID hash2_service_binding_guid = SHIM_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID;
+static EFI_GUID hash2_guid = SHIM_EFI_HASH2_PROTOCOL_GUID;
+static EFI_GUID sm3_guid = SHIM_HASH_ALGORITHM_SM3_GUID;
+static EFI_GUID gIpmiInterfaceProtocolGuid = EFI_TPCM_GUID;
+
+static UINT8 oemSignature[OEM_SIG_SIZE] = {0xDB, 0x07, 0x00};
+
+static shim_efi_ipmi_interface_protocol_t *tpcm_ipmi;
+static UINT32 bm_stage_base = 1500;
+
+static void tpcm_dump_hex(const CHAR16 *name, void *p, int bytes)
+{
+ int i = 0;
+ unsigned char *data = p;
+ int add_newline = 1;
+
+ console_print(L"%s length=%d:\n", name, bytes);
+ while (i < bytes) {
+ console_print(L"%02x ", (unsigned char)data[i]);
+ i++;
+ if (i % 16 == 0) {
+ console_print(L"\n");
+ add_newline = 0;
+ } else {
+ add_newline = 1;
+ }
+ }
+ if (add_newline) {
+ console_print(L"\n");
+ }
+}
+
+static EFI_STATUS tpcm_get_response_blocked(void)
+{
+ shim_ipmi_cmd_header request = {IPMI_BMC_LUN, IPMI_NETFN_OEM, IPMI_CMD_GET_MEASURE_PARM};
+ OEM_BMC_GET_RESULT_REQUSET get_result_request_data;
+ OEM_BMC_GET_RESULT_RESPONSE get_result_response_data;
+ UINT16 timeout_ms = SHIM_IPMI_TIMEOUT_MS;
+ UINT8 response_length;
+ EFI_STATUS efi_status;
+
+ memset(&get_result_request_data, 0, sizeof(get_result_request_data));
+ memset(&get_result_response_data, 0, sizeof(get_result_response_data));
+
+ get_result_request_data.OemSignature[0] = oemSignature[0];
+ get_result_request_data.OemSignature[1] = oemSignature[1];
+ get_result_request_data.OemSignature[OEM_SIG_SIZE - 1] = oemSignature[OEM_SIG_SIZE - 1];
+ get_result_request_data.SubCmd = IPMI_SUB_CMD_CONTROL_REQ;
+ get_result_request_data.FirmwareType = IPMI_FW_SHIM_GRUB;
+ get_result_request_data.FirmwareDetailType = IPMI_FW_DETAIL_GRUB;
+
+ // Polling for 7 seconds
+ while (timeout_ms > 0) {
+ response_length = sizeof(OEM_BMC_GET_RESULT_RESPONSE);
+ msleep(WAIT_TIME_UNIT);
+ timeout_ms -= WAIT_TIME_UNIT;
+
+ console_print(L"get result request: request_size[%d], response_length[%d]\n",
+ sizeof(get_result_request_data), response_length);
+ efi_status = tpcm_ipmi->excute_ipmi_cmd(tpcm_ipmi, request, &get_result_request_data,
+ sizeof(get_result_request_data), &get_result_response_data, &response_length, NULL);
+ console_print(L"OemSignature iana = [ 0x%X %X %X ], ControlResult = %d\n",
+ get_result_response_data.OemSignature[0],
+ get_result_response_data.OemSignature[1],
+ get_result_response_data.OemSignature[OEM_SIG_SIZE - 1],
+ get_result_response_data.ControlResult);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"EFI : attempt to get measurement result failed, ret=%d\n", efi_status);
+ continue;
+ }
+ if (response_length == sizeof(OEM_BMC_GET_RESULT_RESPONSE) &&
+ get_result_response_data.ControlResult != IPMI_MEASURE_UNKNOW) {
+ console_print(L"ipmi protocol: get tpcm measurement result success\n");
+ break;
+ }
+ }
+
+ if (get_result_response_data.ControlResult == IPMI_MEASURE_SUCCESS) {
+ efi_status = EFI_SUCCESS;
+ } else {
+ efi_status = EFI_INVALID_PARAMETER;
+ console_print(L"Error: the tpcm measurement result does not pass, and the startup is rejected");
+ }
+
+ return efi_status;
+}
+
+static void wide_char_to_multi_byte(CHAR16 *description, UINT8 *filename, UINT32 *filename_len)
+{
+ UINT8 *str = (UINT8 *)description;
+ UINT32 len = *filename_len;
+ UINT32 i;
+ *filename_len = 0;
+ for (i = 0; i < len; i++) {
+ if (str[i] == 0 || str[i] == '\\') {
+ continue;
+ }
+ filename[*filename_len] = str[i];
+ (*filename_len)++;
+ }
+ filename[*filename_len] = '\0';
+}
+
+static EFI_STATUS tpcm_fillup_hash_content(OEM_BMC_MEASURE_REQUSET *request_data, unsigned char *content,
+ CHAR16 *description)
+{
+ UINT32 filename_len = StrLen(description) * 2 + 1;
+ UINT32 stage_base = bm_stage_base;
+ UINT8 filename[FIRMWARE_NAME_SIZE] = {0};
+
+ if (filename_len > FIRMWARE_NAME_SIZE) {
+ console_print(L"the path strings is pass the size of FirmwareHashContent.uaObj!\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ wide_char_to_multi_byte(description, filename, &filename_len);
+ console_print(L"start filling the hash content.\n");
+ request_data->FirmwareHashContent.uiCmdTag = TRANS(TPCM_TAG_REQ_COMMAND);
+ request_data->FirmwareHashContent.uiCmdLength = TRANS(sizeof(extern_simple_bmeasure_req_st));
+ request_data->FirmwareHashContent.uiCmdCode = TRANS(TPCM_ORD_ExternSimpleBootMeasure);
+ request_data->FirmwareHashContent.uiPcr = TRANS(0);
+
+ request_data->FirmwareHashContent.uiStage = TRANS(stage_base);
+
+ memcpy((UINT8 *)(request_data->FirmwareHashContent.uaDigest), content, DEFAULT_HASH_SIZE);
+ request_data->FirmwareHashContent.uiObjLen = TRANS(filename_len);
+
+ memcpy((UINT8 *)(request_data->FirmwareHashContent.uaObj), filename, filename_len);
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS tpcm_send_request(unsigned char *content, CHAR16 *description)
+{
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ shim_ipmi_cmd_header request = {IPMI_BMC_LUN, IPMI_NETFN_OEM, IPMI_CMD_GET_MEASURE_PARM};
+ OEM_BMC_MEASURE_REQUSET request_data;
+ OEM_BMC_MEASURE_RESPONSE response_data;
+ UINT8 response_length = sizeof(OEM_BMC_MEASURE_RESPONSE);
+ UINT8 cmd_len = sizeof(extern_simple_bmeasure_req_st);
+
+ memset(&request_data, 0, sizeof(request_data));
+ memset(&response_data, 0, sizeof(response_data));
+
+ request_data.OemSignature[0] = oemSignature[0];
+ request_data.OemSignature[1] = oemSignature[1];
+ request_data.OemSignature[OEM_SIG_SIZE - 1] = oemSignature[OEM_SIG_SIZE - 1];
+ request_data.SubCmd = IPMI_SUB_CMD_MEASURE_REQ;
+ request_data.FirmwareType = IPMI_FW_SHIM_GRUB;
+ request_data.FirmwareDetailType = IPMI_FW_DETAIL_GRUB;
+ request_data.FirmwareHashAlgorithmType = SM3_HASH;
+ request_data.FirmwareHashLen = cmd_len;
+
+ /* filling the hash content of request data */
+ efi_status = tpcm_fillup_hash_content(&request_data, content, description);
+ if (efi_status != EFI_SUCCESS) {
+ goto out;
+ }
+ console_print(L"sizeof(request_data)=%d\n", sizeof(request_data));
+
+ /* send the hash request to tpcm chips by ipmi */
+ efi_status = tpcm_ipmi->excute_ipmi_cmd(tpcm_ipmi, request, &request_data, (UINT8)sizeof(OEM_BMC_MEASURE_REQUSET),
+ &response_data, &response_length, NULL);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"ipmi protocol: excute_ipmi_cmd send request failed.\n");
+ goto out;
+ }
+ console_print(L"ipmi protocol: send tpcm measure request success\n");
+
+out:
+ return efi_status;
+}
+
+static EFI_HANDLE tpcm_efi_service_binding(EFI_GUID *service_binding_guid)
+{
+ EFI_STATUS efi_status;
+ EFI_SERVICE_BINDING *service = NULL;
+ EFI_HANDLE child_dev = NULL;
+
+ efi_status = LibLocateProtocol(service_binding_guid, (VOID **)&service);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"LibLocateProtocol failed\n");
+ return NULL;
+ }
+ if (!service) {
+ console_print(L"couldn't open efi service binding protocol\n");
+ return NULL;
+ }
+ efi_status = service->CreateChild(service, &child_dev);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"Failed to create child device of http service %x\n", efi_status);
+ return NULL;
+ }
+
+ return child_dev;
+}
+
+static EFI_STATUS tpcm_efi_hash2(shim_efi_hash2_protocol_t *hash2, unsigned char *buf, size_t size,
+ unsigned char *output)
+{
+ EFI_STATUS efi_status;
+
+ if (!hash2->hash_init || !hash2->hash_update || !hash2->hash_final) {
+ efi_status = EFI_INVALID_PARAMETER;
+ console_print(L"the functions of hash2 has NULL!\n");
+ goto out;
+ }
+ efi_status = hash2->hash_init(hash2, &sm3_guid);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"hash_init failed.\n");
+ goto out;
+ }
+ efi_status = hash2->hash_update(hash2, buf, size);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"hash_update failed.\n");
+ goto out;
+ }
+ efi_status = hash2->hash_final(hash2, (shim_efi_hash2_output *)output);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"hash_final failed.\n");
+ goto out;
+ }
+
+out:
+ return efi_status;
+}
+
+static EFI_STATUS tpcm_get_hash(unsigned char *buf, size_t size, EFI_HANDLE image_handle, unsigned char *content)
+{
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ shim_efi_hash2_protocol_t *hash2 = NULL;
+ EFI_HANDLE hash_handle = NULL;
+ unsigned char output[DEFAULT_HASH_SIZE] = {0};
+
+ console_print(L"tpcm_get_hash start binding service.\n");
+ hash_handle = tpcm_efi_service_binding(&hash2_service_binding_guid);
+ if (!hash_handle) {
+ console_print(L"hash2 service binding failed.\n");
+ efi_status = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ console_print(L"tpcm_get_hash binding service success.\n");
+
+ efi_status = gBS->OpenProtocol(
+ hash_handle, &hash2_guid, (VOID **)&hash2, image_handle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"tpcm_get_hash: gBS->OpenProtocol fail\n");
+ goto out;
+ }
+ if (!hash2) {
+ console_print(L"hash2 protocol open failed.\n");
+ efi_status = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ console_print(L"tpcm_get_hash get protocol success.\n");
+
+ efi_status = tpcm_efi_hash2(hash2, buf, size, output);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"tpcm_efi_hash2 failed.\n");
+ goto out;
+ }
+
+ tpcm_dump_hex(L"tpcm BIOS hash output: ", output, DEFAULT_HASH_SIZE);
+ memcpy(content, output, DEFAULT_HASH_SIZE);
+
+out:
+ return efi_status;
+}
+
+static EFI_STATUS tpcm_do_measure(unsigned char *buf, size_t size, CHAR16 *description, EFI_HANDLE image_handle)
+{
+ EFI_STATUS efi_status;
+ unsigned char content[DEFAULT_HASH_SIZE] = {0};
+
+ /* step1: get the hash of grub */
+ efi_status = tpcm_get_hash(buf, size, image_handle, content);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"get firmware hash content failed\n");
+ goto out;
+ }
+
+ /* step2: send the measure request to tpcm */
+ efi_status = tpcm_send_request(content, description);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"tpcm_send_request send request failed\n");
+ goto out;
+ }
+
+ /* step3: get the result of measure request */
+ efi_status = tpcm_get_response_blocked();
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"tpcm_get_response_blocked get result failed\n");
+ goto out;
+ }
+
+out:
+ return efi_status;
+}
+
+static void tpcm_get_switch(int *control_flag, int *measure_flag)
+{
+ UINT8 response_length;
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ shim_ipmi_cmd_header request = {IPMI_BMC_LUN, IPMI_NETFN_OEM, IPMI_CMD_GET_MEASURE_PARM};
+ OEM_BMC_GET_RESULT_REQUSET get_tpcm_request_value;
+ OEM_BMC_GET_RESULT_RESPONSE get_tpcm_response_value;
+
+ memset(&get_tpcm_request_value, 0, sizeof(get_tpcm_request_value));
+ memset(&get_tpcm_response_value, 0, sizeof(get_tpcm_response_value));
+
+ get_tpcm_request_value.OemSignature[0] = oemSignature[0];
+ get_tpcm_request_value.OemSignature[1] = oemSignature[1];
+ get_tpcm_request_value.OemSignature[OEM_SIG_SIZE - 1] = oemSignature[OEM_SIG_SIZE - 1];
+ get_tpcm_request_value.SubCmd = IPMI_SUB_CMD_SWITCH_REQ;
+ get_tpcm_request_value.FirmwareType = IPMI_FW_OS;
+ get_tpcm_request_value.FirmwareDetailType = IPMI_FW_DETAIL_GRUB;
+ response_length = sizeof(OEM_BMC_GET_RESULT_RESPONSE);
+
+ if (!tpcm_ipmi->excute_ipmi_cmd) {
+ console_print(L"tpcm_ipmi->excute_ipmi_cmd is NULL, some error may occur below shim!\n");
+ *control_flag = 0;
+ *measure_flag = 0;
+ return;
+ }
+ efi_status = tpcm_ipmi->excute_ipmi_cmd(tpcm_ipmi, request, &get_tpcm_request_value, sizeof(get_tpcm_request_value),
+ &get_tpcm_response_value, &response_length, NULL);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"ipmi get tpcm switch failed.\n");
+ *control_flag = 0;
+ *measure_flag = 0;
+ return;
+ }
+
+ switch (get_tpcm_response_value.ControlResult) {
+ case IPMI_SWITCH_MEASURE_ENABLE_CONTROL_ENABLE:
+ *control_flag = 1;
+ *measure_flag = 1;
+ break;
+ case IPMI_SWITCH_MEASURE_ENABLE_CONTROL_DISABLE:
+ *control_flag = 0;
+ *measure_flag = 1;
+ break;
+ case IPMI_SWITCH_CLOSE:
+ case IPMI_SWITCH_UNKNOW:
+ default:
+ console_print(L"tpcm switch close, skip measure.\n");
+ *control_flag = 0;
+ *measure_flag = 0;
+ break;
+ }
+
+ return;
+}
+
+static EFI_STATUS tpcm_check_ipmi(void)
+{
+ EFI_STATUS efi_status;
+
+ efi_status = LibLocateProtocol(&gIpmiInterfaceProtocolGuid, (VOID **)&tpcm_ipmi);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"tpcm is not support.");
+ return EFI_INVALID_PARAMETER;
+ }
+ if (!tpcm_ipmi) {
+ console_print(L"Error: tpcm_ipmi is NULL");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS tpcm_ipmi_measure(unsigned char *buf, size_t size, void *description, EFI_HANDLE image_handle)
+{
+ EFI_STATUS efi_status;
+ int control_flag, measure_flag;
+
+ /* step1: check if the tpcm chips is existed. */
+ efi_status = tpcm_check_ipmi();
+ if (EFI_ERROR(efi_status)) {
+ return EFI_SUCCESS;
+ }
+
+ /* step2: check if the tpcm switch is on. */
+ efi_status = EFI_SUCCESS;
+ tpcm_get_switch(&control_flag, &measure_flag);
+
+ /* step3: do measure if the tpcm switch is on. */
+ if (measure_flag) {
+ efi_status = tpcm_do_measure(buf, size, description, image_handle);
+ }
+ // If the control switch is not turned on, the communication failure does not affect the startup.
+ if (!control_flag && EFI_ERROR(efi_status)) {
+ console_print(L"WORNING: control switch disable, The tpcm_do_measure() fail doesn't affect the startup.\n");
+ efi_status = EFI_SUCCESS;
+ }
+
+ return efi_status;
+}
+
+EFI_STATUS
+tpcm_measure_grub(void *context, unsigned char *buf, size_t size, EFI_HANDLE image_handle)
+{
+ if (context == NULL || buf == NULL || size == 0) {
+ perror(L"the parameter passed to tpcm_measure_grub is error!\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (StrCmp((CHAR16 *)context, DEFAULT_LOADER)) {
+ console_print(L"only grub is measured by tpcm, not for FALLBACK and MOK_MANAGER.\n");
+ return EFI_SUCCESS;
+ }
+
+ return tpcm_ipmi_measure(buf, size, context, image_handle);
+}
+
diff --git a/tpcm.h b/tpcm.h
new file mode 100644
index 0000000..606c824
--- /dev/null
+++ b/tpcm.h
@@ -0,0 +1,202 @@
+#ifndef SHIM_EFI_TPCM_HEADER
+#define SHIM_EFI_TPCM_HEADER 1
+
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/ocsp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rand.h>
+#include <openssl/crypto.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/rsa.h>
+#include <openssl/dso.h>
+
+#include <Library/BaseCryptLib.h>
+
+#define EFI_TPCM_GUID \
+ { \
+ 0xa37e200e, 0xda90, 0x473b, \
+ { \
+ 0x8b, 0xb5, 0x1d, 0x7b, 0x11, 0xba, 0x32, 0x33 \
+ } \
+ }
+#define SHIM_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID \
+ { \
+ 0xda836f8d, 0x217f, 0x4ca0, \
+ { \
+ 0x99, 0xc2, 0x1c, 0xa4, 0xe1, 0x60, 0x77, 0xea \
+ } \
+ }
+#define SHIM_EFI_HASH2_PROTOCOL_GUID \
+ { \
+ 0x55b1d734, 0xc5e1, 0x49db, \
+ { \
+ 0x96, 0x47, 0xb1, 0x6a, 0xfb, 0xe, 0x30, 0x5b \
+ } \
+ }
+#define SHIM_HASH_ALGORITHM_SM3_GUID \
+ { \
+ 0x9DCD754B, 0x3479, 0x27AD, \
+ { \
+ 0x56, 0x4C, 0x68, 0x7C, 0x68, 0xEC, 0xF9, 0xB9 \
+ } \
+ }
+
+#define OEM_SIG_SIZE 3
+#define FIRMWARE_VERSION_SIZE 32
+#define FIRMWARE_HASH_CONYENT_SIZE 32
+#define FIRMWARE_NAME_SIZE 32
+#define SHIM_IPMI_TIMEOUT_MS 2000
+
+#define IPMI_BMC_LUN 0x00
+/* Net Function Definition */
+#define IPMI_NETFN_OEM 0x30
+
+#define IPMI_CMD_GET_MEASURE_PARM 0x92 // change a name
+
+#define IPMI_SUB_CMD_MEASURE_REQ 0x57 // change a name
+#define IPMI_SUB_CMD_CONTROL_REQ 0x58
+#define IPMI_SUB_CMD_SWITCH_REQ 0x59
+
+#define DEFAULT_HASH_SIZE 32
+#define MEASURE_DATA_MEM_SIZE 0x100000
+
+#define TPCM_TAG_REQ_COMMAND 0x000000C1
+#define TPCM_ORD_ExternSimpleBootMeasure 0x00001053
+
+typedef struct {
+ UINT32 uiCmdTag;
+ UINT32 uiCmdLength;
+ UINT32 uiCmdCode;
+ UINT32 uiPcr;
+ UINT32 uiStage;
+ UINT8 uaDigest[DEFAULT_HASH_SIZE];
+ UINT32 uiObjLen;
+ UINT8 uaObj[FIRMWARE_NAME_SIZE];
+} extern_simple_bmeasure_req_st;
+
+typedef struct {
+ UINT8 OemSignature[OEM_SIG_SIZE];
+ UINT8 SubCmd;
+ UINT8 FirmwareType;
+ UINT8 FirmwareDetailType;
+ UINT8 FirmwareHashAlgorithmType;
+ UINT8 FirmwareHashLen;
+ extern_simple_bmeasure_req_st FirmwareHashContent;
+ UINT8 FirmwareVerionLen;
+ UINT8 FirmwareVerion[FIRMWARE_VERSION_SIZE];
+} OEM_BMC_MEASURE_REQUSET;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 OemSignature[OEM_SIG_SIZE];
+} OEM_BMC_MEASURE_RESPONSE;
+
+typedef struct {
+ UINT8 OemSignature[OEM_SIG_SIZE];
+ UINT8 SubCmd;
+ UINT8 FirmwareType;
+ UINT8 FirmwareDetailType;
+} OEM_BMC_GET_RESULT_REQUSET;
+
+typedef struct {
+ UINT8 OemSignature[OEM_SIG_SIZE];
+ UINT8 ControlResult;
+} OEM_BMC_GET_RESULT_RESPONSE;
+
+typedef enum {
+ IPMI_SYSTEM_INTERFACE_UNKNOWN, // IPMI_SYSTEM_INTERFACE_TYPE->UNKNOWN
+ IPMI_SYSTEM_INTERFACE_KCS,
+ IPMI_SYSTEM_INTERFACE_SMIC,
+ IPMI_SYSTEM_INTERFACE_BT, // IPMI_SYSTEM_INTERFACE_TYPE->BT
+ IPMI_SYSTEM_INTERFACE_SSIF,
+ IPMI_SYSTEM_INTERFACE_MAX_TYPE // IPMI_SYSTEM_INTERFACE_TYPE->MAX_TYPE
+} shim_ipmi_system_interface_type;
+
+typedef struct {
+ UINT8 lun : 2;
+ UINT8 net_fn : 6;
+ UINT8 cmd;
+} shim_ipmi_cmd_header;
+
+typedef enum {
+ IPMI_MEMORY,
+ IPMI_IO,
+ IPMI_MAX_INTERFACE_ADDRESS_TYPE
+} shim_ipmi_interface_address_type;
+
+typedef enum {
+ IPMI_FW_SHIM,
+ IPMI_FW_SHIM_GRUB,
+ IPMI_FW_OS
+} shim_ipmi_firmware_type;
+
+typedef enum {
+ IPMI_FW_DETAIL_GRUB,
+ RESERVED1,
+ RESERVED2
+} shim_ipmi_firmware_detail_type;
+
+typedef enum {
+ SM3_HASH,
+ HASH_RESERVED1,
+ HASH_RESERVED2
+} shim_ipmi_firmware_hash_type;
+
+typedef enum {
+ IPMI_MEASURE_UNKNOW,
+ IPMI_MEASURE_SUCCESS,
+ IPMI_MEASURE_FAIL
+} shim_ipmi_measure_result_type;
+
+typedef enum {
+ IPMI_SWITCH_UNKNOW,
+ IPMI_SWITCH_MEASURE_ENABLE_CONTROL_ENABLE,
+ IPMI_SWITCH_CLOSE,
+ IPMI_SWITCH_MEASURE_ENABLE_CONTROL_DISABLE
+} shim_ipmi_get_switch_result_type;
+
+typedef union {
+ UINT8 Md5Hash[16];
+ UINT8 Sha1Hash[20];
+ UINT8 Sha224Hash[28];
+ UINT8 Sha256Hash[32];
+ UINT8 Sha384Hash[48];
+ UINT8 Sha512Hash[64];
+ UINT8 Sm3Hash[32];
+} shim_efi_hash2_output;
+
+struct shim_efi_hash2_protocol {
+ EFI_STATUS (*get_hash_size)(struct shim_efi_hash2_protocol *this, EFI_GUID *hash_algorithm, UINT64 hash_size);
+
+ EFI_STATUS (*hash)
+ (struct shim_efi_hash2_protocol *this, EFI_GUID *hash_algorithm, UINT8 *message, UINT64 message_size,
+ shim_efi_hash2_output *hash);
+
+ EFI_STATUS (*hash_init)(struct shim_efi_hash2_protocol *this, EFI_GUID *hash_algorithm);
+
+ EFI_STATUS (*hash_update)(struct shim_efi_hash2_protocol *this, UINT8 *message, UINT64 message_size);
+
+ EFI_STATUS (*hash_final)(struct shim_efi_hash2_protocol *this, shim_efi_hash2_output *hash);
+};
+
+typedef struct shim_efi_hash2_protocol shim_efi_hash2_protocol_t;
+
+struct shim_efi_ipmi_interface_protocol {
+ EFI_STATUS (*excute_ipmi_cmd)
+ (struct shim_efi_ipmi_interface_protocol *this, shim_ipmi_cmd_header request, void *send_data, UINT8 send_length,
+ void *recv_data, UINT8 *recv_length, UINT16 *status_codes);
+ shim_ipmi_system_interface_type (*get_ipmi_interface_type)(struct shim_efi_ipmi_interface_protocol *this);
+ UINT16 (*get_ipmi_base_address)(struct shim_efi_ipmi_interface_protocol *this);
+ shim_ipmi_interface_address_type (*get_ipmi_base_address_type)(struct shim_efi_ipmi_interface_protocol *this);
+ UINT8 (*get_ipmi_version)(struct shim_efi_ipmi_interface_protocol *this);
+};
+
+typedef struct shim_efi_ipmi_interface_protocol shim_efi_ipmi_interface_protocol_t;
+
+EFI_STATUS tpcm_measure_grub(void *context, unsigned char *buf, size_t size, EFI_HANDLE image_handle);
+
+#endif
--
2.27.0

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,48 @@
From b078ef274887a4cc0da64fd6668800d1e24a2871 Mon Sep 17 00:00:00 2001
From: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
Date: Tue, 16 May 2023 14:31:13 -0700
Subject: [PATCH] Always clear SbatLevel when Secure Boot is disabled
Unless an explict sbat policy is specified, always delete SbatLevel
when secure boot is disabled.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
---
sbat.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/sbat.c b/sbat.c
index f1d6e98..cdf4e93 100644
--- a/sbat.c
+++ b/sbat.c
@@ -412,7 +412,12 @@ set_sbat_uefi_variable(void)
&attributes);
if (EFI_ERROR(efi_status)) {
dprint("Default sbat policy: previous\n");
- sbat_var = SBAT_VAR_PREVIOUS;
+ if (secure_mode()) {
+ sbat_var = SBAT_VAR_PREVIOUS;
+ } else {
+ reset_sbat = true;
+ sbat_var = SBAT_VAR_ORIGINAL;
+ }
} else {
switch (*sbat_policy) {
case SBAT_POLICY_LATEST:
@@ -438,7 +443,12 @@ set_sbat_uefi_variable(void)
default:
console_error(L"SBAT policy state %llu is invalid",
EFI_INVALID_PARAMETER);
- sbat_var = SBAT_VAR_PREVIOUS;
+ if (secure_mode()) {
+ sbat_var = SBAT_VAR_PREVIOUS;
+ } else {
+ reset_sbat = true;
+ sbat_var = SBAT_VAR_ORIGINAL;
+ }
clear_sbat_policy();
break;
}
--
2.33.0

View File

@ -0,0 +1,56 @@
From b013765abfa80036dc779dd0e50602c57bb3bf95 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 7 Mar 2023 16:52:55 +0000
Subject: [PATCH] Ensure that EXFLAG_INVALID_POLICY is checked even in
leaf
certs
Even though we check the leaf cert to confirm it is valid, we
later ignored the invalid flag and did not notice that the leaf
cert was bad.
Fixes: CVE-2023-0465
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20588)
Reference:https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=b013765abfa80036dc779dd0e50602c57bb3bf95
Conflict: Context conflict
---
Cryptlib/OpenSSL/crypto/x509/x509_vfy.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c b/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
index 96f306b..a6878fe 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
@@ -1768,16 +1768,23 @@ static int check_policy(X509_STORE_CTX *ctx)
* Locate certificates with bad extensions and notify callback.
*/
X509 *x;
- int i;
- for (i = 1; i < sk_X509_num(ctx->chain); i++) {
+ int i, cbcalled = 0;
+ for (i = 0; i < sk_X509_num(ctx->chain); i++) {
x = sk_X509_value(ctx->chain, i);
if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
continue;
+ cbcalled = 1;
ctx->current_cert = x;
ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
if (!ctx->verify_cb(0, ctx))
return 0;
}
+ if (!cbcalled) {
+ /* Should not be able to get here */
+ X509err(X509_F_CHECK_POLICY, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ /* The callback ignored the error so we return success */
return 1;
}
if (ret == -2) {
--
2.33.0

View File

@ -0,0 +1,67 @@
From 423a2bc737a908ad0c77bda470b2b59dc879936b Mon Sep 17 00:00:00 2001
From: Richard Levitte <levitte@openssl.org>
Date: Fri, 12 May 2023 10:00:13 +0200
Subject: [PATCH] Restrict the size of OBJECT IDENTIFIERs that OBJ_obj2txt will
translate
Reference:https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=423a2bc737a908ad0c77bda470b2b59dc879936b
Conflict:NA
OBJ_obj2txt() would translate any size OBJECT IDENTIFIER to canonical
numeric text form. For gigantic sub-identifiers, this would take a very
long time, the time complexity being O(n^2) where n is the size of that
sub-identifier.
To mitigate this, a restriction on the size that OBJ_obj2txt() will
translate to canonical numeric text form is added, based on RFC 2578
(STD 58), which says this:
> 3.5. OBJECT IDENTIFIER values
>
> An OBJECT IDENTIFIER value is an ordered list of non-negative numbers.
> For the SMIv2, each number in the list is referred to as a sub-identifier,
> there are at most 128 sub-identifiers in a value, and each sub-identifier
> has a maximum value of 2^32-1 (4294967295 decimal).
Fixes otc/security#96
Fixes CVE-2023-2650
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
crypto/objects/obj_dat.c | 19 +++++++++++++++++++
1 files changed, 50 insertions(+)
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index 01cde00e98..c0e55197a0 100644
--- a/Cryptlib/OpenSSL/crypto/objects/obj_dat.c
+++ b/Cryptlib/OpenSSL/crypto/objects/obj_dat.c
@@ -443,6 +443,25 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
first = 1;
bl = NULL;
+ /*
+ * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs:
+ *
+ * > 3.5. OBJECT IDENTIFIER values
+ * >
+ * > An OBJECT IDENTIFIER value is an ordered list of non-negative
+ * > numbers. For the SMIv2, each number in the list is referred to as a
+ * > sub-identifier, there are at most 128 sub-identifiers in a value,
+ * > and each sub-identifier has a maximum value of 2^32-1 (4294967295
+ * > decimal).
+ *
+ * So a legitimate OID according to this RFC is at most (32 * 128 / 7),
+ * i.e. 586 bytes long.
+ *
+ * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
+ */
+ if (len > 586)
+ goto err;
+
while (len > 0) {
l = 0;
use_bn = 0;
--
2.34.1

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,111 @@
From f77095c2543ffc1eda06556092de7badac343883 Mon Sep 17 00:00:00 2001
From: j30031148 <jinlun@huawei.com>
Date: Mon, 19 Feb 2024 14:47:30 +0800
Subject: [PATCH] CVE-2024-0727
Reference:https://gitee.com/openeuler/openssl/commit/09015a582baa980dc04f635504b16fe95dc3790b
Conflict:NA
---
Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c | 16 ++++++++++++++++
Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c | 5 +++++
Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c | 5 +++--
Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c | 8 ++++++--
4 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c
index d9f03a3..42a73e0 100644
--- a/Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c
@@ -171,6 +171,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
+
+ if (p7->d.data == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, PKCS12_R_DECODE_ERROR);
+ return NULL;
+ }
+
return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
}
@@ -226,6 +232,11 @@ 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) {
+ return NULL;
+ }
+
return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
pass, passlen,
@@ -253,6 +264,11 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12)
PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
+ if (p12->authsafes->d.data == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, PKCS12_R_DECODE_ERROR);
+ return NULL;
+ }
+
return ASN1_item_unpack(p12->authsafes->d.data,
ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c
index cbf34da..bda3c28 100644
--- a/Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c
@@ -80,6 +80,11 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
return 0;
}
+ if (p12->authsafes->d.data == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_DECODE_ERROR);
+ return 0;
+ }
+
salt = p12->mac->salt->data;
saltlen = p12->mac->salt->length;
if (!p12->mac->iter)
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c
index 9e8ebb2..19a855b 100644
--- a/Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c
@@ -126,8 +126,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/Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c
index 62fb299..e895deb 100644
--- a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c
@@ -78,10 +78,14 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
{
STACK_OF(X509_ALGOR) *mdalgs;
int ctype_nid = OBJ_obj2nid(p7->type);
- 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.27.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,105 @@
From de8c3582d2eb280bf6b358349e04a959b945f1a5 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Fri, 1 Jul 2022 15:52:51 -0400
Subject: [PATCH] aarch64: Keep _relocate() from being dirtied by _relocate()
[Patch is a gnu-efi patch we apply to the bundled copy.]
This could all be wrong, but the fix seems to work. Here's my theory of
what's going on. We have a bug report that says:
No EFI system partition
Booting /efi\boot\bootaa64.efi
No EFI system partition
Failed to persist EFI variables
"Synchronous Abort" handler, esr 0x02000000
elr: fffffffffeb48a28 lr : fffffffffeb3f024 (reloc)
elr: 000000003ca1aa28 lr : 000000003ca11024
x0 : 000000003ca0d000 x1 : 000000003ca22018
x2 : 000000003ca22000 x3 : 0000000000000018
x4 : 0000000000001488 x5 : 0000000000000000
x6 : 0000000000001000 x7 : 0000000000000000
x8 : 0000000000000007 x9 : 0000000000003ca0
x10: 000000003ca3e040 x11: 00000000b0b87665
x12: 000000007c70ea25 x13: 000000005a827999
x14: 000000006ed9eba1 x15: 000000008f1bbcdc
x16: 000000003df97394 x17: 00000000b7ce40b7
x18: 0000000000000011 x19: 000000003caeb000
x20: 0000000000000000 x21: 000000003dc1ba50
x22: 000000003caff2f8 x23: 0000000000000001
x24: 000000003caff000 x25: 000000003caff3c0
x26: 000000003caff3c8 x27: 000000003caff3d0
x28: 000000003caff3d8 x29: 000000003db3e600
Code: 8b000021 f82068a1 8b030042 cb030084 (f100009f)
UEFI image [0x000000003ca0d000:0x000000003ca24fff] pc=0xda28 '/efi\boot\fbaa64.efi'
Resetting CPU ...
resetting ...
When I disassemble it, "8b000021 f82068a1 8b030042 cb030084 (f100009f)"
at 0xda28 (aka 0x3ca1aa28 in our register dump above) is:
da18: 8b000021 add x1, x1, x0
da1c: f82068a1 str x1, [x5, x0]
da20: 8b030042 add x2, x2, x3
da24: cb030084 sub x4, x4, x3
da28: f100009f cmp x4, #0x0
Of course the Arm ARM says "cmp" cannot fault in this way, and %esr is
less than helpful, for reasons I don't understand. I believe what is
happening is this. Farther up in the file is the function
StatusToString(), as seen here:
000000000000d960 <StatusToString>:
d960: d0000022 adrp x2, 13000 <gEfiGraphicsOutputProtocolGuid+0x8>
d964: aa0103e3 mov x3, x1
d968: 911f0042 add x2, x2, #0x7c0
d96c: f9400441 ldr x1, [x2, #8]
d970: b5000081 cbnz x1, d980 <StatusToString+0x20>
d974: b0000022 adrp x2, 12000 <CSWTCH.43+0x516>
d978: 91124842 add x2, x2, #0x492
d97c: 17fffc32 b ca44 <SPrint>
d980: f8410444 ldr x4, [x2], #16
d984: eb03009f cmp x4, x3
d988: 54ffff21 b.ne d96c <StatusToString+0xc> // b.any
d98c: 17fffe47 b d2a8 <StrCpy>
I believe when _relocate() gets to the relocations for 0xd960 the page
being processed is evicted from the i$ and moved into the d$, and then
when execution continues, the i$ raises an exception because it doesn't
have the page in question, and it can't stall execution to fill it,
because it's now owned (and dirty) in the other cache.
There are a couple of ways to solve this, but I've taken the laziest
one: align the code in _relocate() to its own page boundary. This
partially works because our link order means this code is actually the
last function in .text, and so no relocations will ever land on this
page.
Signed-off-by: Peter Jones <pjones@redhat.com>
[rharwood@redhat.com: adapt to shim]
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
---
gnu-efi/gnuefi/reloc_aarch64.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gnu-efi/gnuefi/reloc_aarch64.c b/gnu-efi/gnuefi/reloc_aarch64.c
index 086727961c2..0022abdaca7 100644
--- a/gnu-efi/gnuefi/reloc_aarch64.c
+++ b/gnu-efi/gnuefi/reloc_aarch64.c
@@ -48,6 +48,11 @@ EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
unsigned long *addr;
int i;
+ /*
+ * We need this code to not be on the same page as any relocations.
+ */
+ __asm__(".balign 4096\n");
+
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
switch (dyn[i].d_tag) {
case DT_RELA:
--
2.35.1

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
Version: 15.6
Release: 16
Release: 23
Summary: First-stage UEFI bootloader
ExclusiveArch: x86_64 aarch64
License: BSD
@ -73,6 +73,20 @@ Patch35:backport-pe-only-process-RelocDir-Size-of-reloc-section.patch
Patch36:backport-Correctly-free-memory-allocated-in-handle_image.patch
Patch37:backport-CVE-2023-3446.patch
Patch38:backport-CVE-2023-5678.patch
Patch39: backport-aarch64-Keep-_relocate-from-being-dirtied-by-_reloca.patch
Patch40:backport-CVE-2023-40551-pe-relocate-Fix-bounds-check-for-MZ-b.patch
Patch41:backport-pe-relocate-make-read_header-use-checked-arithmetic-.patch
Patch42:backport-Add-primitives-for-overflow-checked-arithmetic-opera.patch
Patch43:backport-CVE-2023-40550-pe-Fix-an-out-of-bound-read-in-verify.patch
Patch44:backport-pe-relocate-Ensure-nothing-else-implements-CVE-2023-40550.patch
Patch45:backport-CVE-2023-40548-Fix-integer-overflow-on-SBAT-section-.patch
Patch46:backport-CVE-2023-40547-avoid-incorrectly-trusting-HTTP-heade.patch
Patch47:backport-Further-mitigations-against-CVE-2023-40546-as-a-clas.patch
Patch48:backport-CVE-2023-40549-Authenticode-verify-that-the-signatur.patch
Patch49: backport-CVE-2023-2650.patch
Patch50: backport-CVE-2023-0465.patch
Patch51: backport-CVE-2024-0727.patch
Patch52: backport-Always-clear-SbatLevel-when-Secure-Boot-is-disabled.patch
# Feature for shim SMx support
Patch9000:Feature-shim-openssl-add-ec-support.patch
@ -81,6 +95,9 @@ Patch9002:Feature-shim-openssl-add-sm2-and-sm3-support.patch
Patch9003:Feature-shim-cryptlib-support-sm2-signature-verify.patch
Patch9004:Feature-shim-support-sm2-and-sm3-algorithm.patch
# Feature for shim TPCM support
Patch9005:Feature-add-tpcm-support-with-ipmi-channel.patch
BuildRequires: elfutils-libelf-devel openssl-devel openssl git pesign gnu-efi gnu-efi-devel gcc vim-common efivar-devel
%if 0%{?openEuler_sign_rsa}
@ -176,6 +193,12 @@ install -m 0700 %{SOURCE1} ${RPM_BUILD_ROOT}/%{shimefivendor}
install -m 0700 %{SOURCE2} ${RPM_BUILD_ROOT}/%{shimefivendor}
%endif
%if "%{_vendor}" != "openEuler"
iconv -f UTF-16LE -t UTF-8 ${RPM_BUILD_ROOT}/%{shimefivendor}/%{bootcsv} > /tmp/%{bootcsv}.tmp
sed -i -e 's/openeuler/%{_vendor}/g' -e 's/openEuler/%{_vendor}/g' /tmp/%{bootcsv}.tmp
iconv -f UTF-8 -t UTF-16LE /tmp/%{bootcsv}.tmp > ${RPM_BUILD_ROOT}/%{shimefivendor}/%{bootcsv}
%endif
# install the debug symbols
install -d ${RPM_BUILD_ROOT}/usr/lib/debug/%{shimefivendor}
install -m 644 fb%{efi_arch}.efi.debug ${RPM_BUILD_ROOT}/usr/lib/debug/%{shimefivendor}
@ -207,6 +230,27 @@ make test
/usr/src/debug/%{name}-%{version}-%{release}/*
%changelog
* Tue May 7 2024 jinlun <jinlun@huawei.com> - 15.6-23
- Fix the TPCM feature issue
* Tue Apr 23 2024 lijuzhang <lijuzhang@inspur.com> - 15.6-22
- replace vendor for BOOTX64.CSV or BOOTAA64.CSV
* Tue Apr 23 2024 jinlun <jinlun@huawei.com> - 15.6-21
- add tpcm support with ipmi channel
* Tue Mar 26 2024 yixiangzhike <yixiangzhike007@163.com> - 15.6-20
- backport patch from upstream
* Wed Feb 28 2024 zhengxiaoxiao <zhengxiaoxiao2@huawei.com> - 15.6-19
- fix CVE-2023-0465 CVE-2023-2650 CVE-2024-0727
* Tue Jan 30 2024 zhengxiaoxiao <zhengxiaoxiao2@huawei.com> - 15.6-18
- fix CVE-2023-40547 CVE-2023-40548 CVE-2023-40549 CVE-2023-40550 CVE-2023-40551
* Mon Dec 25 2023 zhangruifang <zhangruifang@h-partners.com> - 15.6-17
- backport patchs from upstream
* Mon Dec 18 2023 jinlun <jinlun@huawei.com> - 15.6-16
- fix CVE-2023-3446 CVE-2023-5678