Fix range check bugs
This is a patch hunting for fuzzing failures and adding
appropriate range checks.
Change-Id: Ieae02b7e461b9a6c5e25de6c663a768f7a0d5e10
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/cper-parse.c b/cper-parse.c
index 54f4cde..8b62ef6 100644
--- a/cper-parse.c
+++ b/cper-parse.c
@@ -411,14 +411,15 @@
return section_descriptor_ir;
}
-json_object *read_section(const unsigned char *cper_section_buf,
- CPER_SECTION_DEFINITION *definition,
- json_object **section_ir)
+json_object *read_section(const unsigned char *cper_section_buf, size_t size,
+ CPER_SECTION_DEFINITION *definition)
{
- *section_ir = definition->ToIR(cper_section_buf);
-
+ if (definition->ToIR == NULL) {
+ return NULL;
+ }
+ json_object *section_ir = definition->ToIR(cper_section_buf, size);
json_object *result = json_object_new_object();
- json_object_object_add(result, definition->ShortName, *section_ir);
+ json_object_object_add(result, definition->ShortName, section_ir);
return result;
}
@@ -435,15 +436,14 @@
json_object *result = NULL;
json_object *section_ir = NULL;
- int section_converted = 0;
for (size_t i = 0; i < section_definitions_len; i++) {
if (!guid_equal(section_definitions[i].Guid,
&descriptor->SectionType)) {
continue;
}
- result = read_section(cper_section_buf, §ion_definitions[i],
- §ion_ir);
- section_converted = 1;
+ result = read_section(cper_section_buf, size,
+ §ion_definitions[i]);
+
break;
}
@@ -453,23 +453,21 @@
// a match, try to force a match so we get some coverage. Note, we still
// want coverage of the section failed to convert code, so treat index ==
// size as section failed to convert.
- if (!section_converted) {
+ if (result == NULL) {
unsigned char index = 0;
if (index > 0) {
index = descriptor->SectionType.Data1 %
section_definitions_len;
}
if (index < section_definitions_len) {
- result = read_section(cper_section_buf,
- §ion_definitions[index],
- §ion_ir);
- section_converted = 1;
+ result = read_section(cper_section_buf, size,
+ §ion_definitions[index]);
}
}
#endif
//Was it an unknown GUID/failed read?
- if (!section_converted) {
+ if (result == NULL) {
//Output the data as formatted base64.
int32_t encoded_len = 0;
char *encoded = base64_encode(cper_section_buf,
diff --git a/include/libcper/sections/cper-section-ampere.h b/include/libcper/sections/cper-section-ampere.h
index 013a59f..b03f2da 100644
--- a/include/libcper/sections/cper-section-ampere.h
+++ b/include/libcper/sections/cper-section-ampere.h
@@ -5,7 +5,7 @@
#include <json.h>
#include <libcper/Cper.h>
-json_object *cper_section_ampere_to_ir(const void *section);
+json_object *cper_section_ampere_to_ir(const UINT8 *section, UINT32 size);
void ir_section_ampere_to_cper(json_object *section, FILE *out);
#endif
diff --git a/include/libcper/sections/cper-section-arm.h b/include/libcper/sections/cper-section-arm.h
index c1c7f75..5433f80 100644
--- a/include/libcper/sections/cper-section-arm.h
+++ b/include/libcper/sections/cper-section-arm.h
@@ -77,6 +77,8 @@
"Device Memory Access" }
#define ARM_PROCESSOR_INFO_REGISTER_CONTEXT_TYPES_KEYS \
(int[]){ 0, 1, 2, 3, 4, 5, 6, 7, 8 }
+#define ARM_BUS_ADDRESS_SPACE_TYPES_COUNT 9
+
#define ARM_PROCESSOR_INFO_REGISTER_CONTEXT_TYPES_VALUES \
(const char *[]){ "AArch32 General Purpose Registers", \
"AArch32 EL1 Context Registers", \
@@ -129,7 +131,7 @@
"sctlr_el3", "sp_el3", "spsr_el3", "tcr_el3", \
"tpidr_el3", "ttbr0_el3" }
-json_object *cper_section_arm_to_ir(const void *section);
+json_object *cper_section_arm_to_ir(const UINT8 *section, UINT32 size);
void ir_section_arm_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-ccix-per.h b/include/libcper/sections/cper-section-ccix-per.h
index a2b858f..256954c 100644
--- a/include/libcper/sections/cper-section-ccix-per.h
+++ b/include/libcper/sections/cper-section-ccix-per.h
@@ -24,7 +24,7 @@
UINT16 Reserved;
} __attribute__((packed, aligned(1))) EFI_CCIX_PER_LOG_DATA;
-json_object *cper_section_ccix_per_to_ir(const void *section);
+json_object *cper_section_ccix_per_to_ir(const UINT8 *section, UINT32 size);
void ir_section_ccix_per_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-cxl-component.h b/include/libcper/sections/cper-section-cxl-component.h
index 5f1c400..3e3eb5c 100644
--- a/include/libcper/sections/cper-section-cxl-component.h
+++ b/include/libcper/sections/cper-section-cxl-component.h
@@ -35,7 +35,8 @@
UINT64 DeviceSerial;
} __attribute__((packed, aligned(1))) EFI_CXL_COMPONENT_EVENT_HEADER;
-json_object *cper_section_cxl_component_to_ir(const void *section);
+json_object *cper_section_cxl_component_to_ir(const UINT8 *section,
+ UINT32 size);
void ir_section_cxl_component_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-cxl-protocol.h b/include/libcper/sections/cper-section-cxl-protocol.h
index cdf23a0..f707003 100644
--- a/include/libcper/sections/cper-section-cxl-protocol.h
+++ b/include/libcper/sections/cper-section-cxl-protocol.h
@@ -63,7 +63,7 @@
UINT32 Reserved;
} __attribute__((packed, aligned(1))) EFI_CXL_PROTOCOL_ERROR_DATA;
-json_object *cper_section_cxl_protocol_to_ir(const void *section);
+json_object *cper_section_cxl_protocol_to_ir(const UINT8 *section, UINT32 size);
void ir_section_cxl_protocol_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-dmar-generic.h b/include/libcper/sections/cper-section-dmar-generic.h
index a2eb08e..3376dd5 100644
--- a/include/libcper/sections/cper-section-dmar-generic.h
+++ b/include/libcper/sections/cper-section-dmar-generic.h
@@ -43,7 +43,7 @@
#define DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS (int[]){ 0x0, 0x1 }
#define DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES (const char *[]){ "VT-d", "IOMMU" }
-json_object *cper_section_dmar_generic_to_ir(const void *section);
+json_object *cper_section_dmar_generic_to_ir(const UINT8 *section, UINT32 size);
void ir_section_dmar_generic_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-dmar-iommu.h b/include/libcper/sections/cper-section-dmar-iommu.h
index 9192e38..5bee4d4 100644
--- a/include/libcper/sections/cper-section-dmar-iommu.h
+++ b/include/libcper/sections/cper-section-dmar-iommu.h
@@ -9,7 +9,7 @@
#include <json.h>
#include <libcper/Cper.h>
-json_object *cper_section_dmar_iommu_to_ir(const void *section);
+json_object *cper_section_dmar_iommu_to_ir(const UINT8 *section, UINT32 size);
void ir_section_dmar_iommu_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-dmar-vtd.h b/include/libcper/sections/cper-section-dmar-vtd.h
index 68a1d79..3d248d1 100644
--- a/include/libcper/sections/cper-section-dmar-vtd.h
+++ b/include/libcper/sections/cper-section-dmar-vtd.h
@@ -28,7 +28,7 @@
UINT64 Resv3 : 1;
} EFI_VTD_FAULT_RECORD;
-json_object *cper_section_dmar_vtd_to_ir(const void *section);
+json_object *cper_section_dmar_vtd_to_ir(const UINT8 *section, UINT32 size);
void ir_section_dmar_vtd_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-firmware.h b/include/libcper/sections/cper-section-firmware.h
index fb21cfb..87614dc 100644
--- a/include/libcper/sections/cper-section-firmware.h
+++ b/include/libcper/sections/cper-section-firmware.h
@@ -15,7 +15,7 @@
"SOC Firmware Error Record (Type1 Legacy)", \
"SOC Firmware Error Record (Type2)" }
-json_object *cper_section_firmware_to_ir(const void *section);
+json_object *cper_section_firmware_to_ir(const UINT8 *section, UINT32 size);
void ir_section_firmware_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-generic.h b/include/libcper/sections/cper-section-generic.h
index ac041d4..bc7c112 100644
--- a/include/libcper/sections/cper-section-generic.h
+++ b/include/libcper/sections/cper-section-generic.h
@@ -39,7 +39,7 @@
#define GENERIC_FLAGS_BITFIELD_NAMES \
(const char *[]){ "restartable", "preciseIP", "overflow", "corrected" }
-json_object *cper_section_generic_to_ir(const void *section);
+json_object *cper_section_generic_to_ir(const UINT8 *section, UINT32 size);
void ir_section_generic_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-ia32x64.h b/include/libcper/sections/cper-section-ia32x64.h
index 32f7826..b3a1233 100644
--- a/include/libcper/sections/cper-section-ia32x64.h
+++ b/include/libcper/sections/cper-section-ia32x64.h
@@ -66,6 +66,9 @@
"64-bit Mode Debug Registers", \
"Memory Mapper Registers" }
+#define IA32X64_REGISTER_CONTEXT_TYPES_SIZE \
+ ((sizeof(IA32X64_REGISTER_CONTEXT_TYPES_KEYS) / sizeof(int)))
+
typedef struct {
UINT64 Eax;
UINT64 Ebx;
@@ -74,7 +77,7 @@
UINT64 Reserved[2];
} EFI_IA32_X64_CPU_ID;
-json_object *cper_section_ia32x64_to_ir(const void *section);
+json_object *cper_section_ia32x64_to_ir(const UINT8 *section, UINT32 size);
void ir_section_ia32x64_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-ipf.h b/include/libcper/sections/cper-section-ipf.h
index be985b4..0541d65 100644
--- a/include/libcper/sections/cper-section-ipf.h
+++ b/include/libcper/sections/cper-section-ipf.h
@@ -65,7 +65,7 @@
UINT64 Frs[256];
} EFI_IPF_PSI_STATIC;
-json_object *cper_section_ipf_to_ir(const void *section);
+json_object *cper_section_ipf_to_ir(const UINT8 *section, UINT32 size);
#ifdef __cplusplus
}
diff --git a/include/libcper/sections/cper-section-memory.h b/include/libcper/sections/cper-section-memory.h
index f759f1d..e8536dd 100644
--- a/include/libcper/sections/cper-section-memory.h
+++ b/include/libcper/sections/cper-section-memory.h
@@ -75,8 +75,10 @@
"bankGroupValid", \
"bankAddressValid" }
-json_object *cper_section_platform_memory_to_ir(const void *section);
-json_object *cper_section_platform_memory2_to_ir(const void *section);
+json_object *cper_section_platform_memory_to_ir(const UINT8 *section,
+ UINT32 size);
+json_object *cper_section_platform_memory2_to_ir(const UINT8 *section,
+ UINT32 size);
void ir_section_memory_to_cper(json_object *section, FILE *out);
void ir_section_memory2_to_cper(json_object *section, FILE *out);
diff --git a/include/libcper/sections/cper-section-nvidia.h b/include/libcper/sections/cper-section-nvidia.h
index df85792..cca9097 100644
--- a/include/libcper/sections/cper-section-nvidia.h
+++ b/include/libcper/sections/cper-section-nvidia.h
@@ -9,7 +9,7 @@
#include <json.h>
#include <libcper/Cper.h>
-json_object *cper_section_nvidia_to_ir(const void *section);
+json_object *cper_section_nvidia_to_ir(const UINT8 *section, UINT32 size);
void ir_section_nvidia_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-pci-bus.h b/include/libcper/sections/cper-section-pci-bus.h
index c4de3be..906af48 100644
--- a/include/libcper/sections/cper-section-pci-bus.h
+++ b/include/libcper/sections/cper-section-pci-bus.h
@@ -26,7 +26,7 @@
"Address Parity Error", \
"Command Parity Error" }
-json_object *cper_section_pci_bus_to_ir(const void *section);
+json_object *cper_section_pci_bus_to_ir(const UINT8 *section, UINT32 size);
void ir_section_pci_bus_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-pci-dev.h b/include/libcper/sections/cper-section-pci-dev.h
index 696a44b..cb6321c 100644
--- a/include/libcper/sections/cper-section-pci-dev.h
+++ b/include/libcper/sections/cper-section-pci-dev.h
@@ -29,14 +29,25 @@
} EFI_PCI_PCIX_DEVICE_ID_INFO;
typedef struct {
+ UINT64 Address;
+ UINT64 Value;
+} EFI_PCI_PCIX_DEVICE_ERROR_DATA_REGISTER;
+
+typedef struct {
UINT64 ValidFields;
EFI_GENERIC_ERROR_STATUS ErrorStatus;
EFI_PCI_PCIX_DEVICE_ID_INFO IdInfo;
UINT32 MemoryNumber;
UINT32 IoNumber;
+ // Keep this at the end of this struct
+ // and allocate based on NumberRegs
+#ifndef __cplusplus
+ EFI_PCI_PCIX_DEVICE_ERROR_DATA_REGISTER MemoryRegister[];
+#endif
+
} __attribute__((packed, aligned(1))) EFI_PCI_PCIX_DEVICE_ERROR_DATA;
-json_object *cper_section_pci_dev_to_ir(const void *section);
+json_object *cper_section_pci_dev_to_ir(const UINT8 *section, UINT32 size);
void ir_section_pci_dev_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section-pcie.h b/include/libcper/sections/cper-section-pcie.h
index 05307aa..93206b7 100644
--- a/include/libcper/sections/cper-section-pcie.h
+++ b/include/libcper/sections/cper-section-pcie.h
@@ -30,7 +30,7 @@
"Root Complex Integrated Endpoint Device", \
"Root Complex Event Collector" }
-json_object *cper_section_pcie_to_ir(const void *section);
+json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size);
void ir_section_pcie_to_cper(json_object *section, FILE *out);
#ifdef __cplusplus
diff --git a/include/libcper/sections/cper-section.h b/include/libcper/sections/cper-section.h
index 5874edf..1945b1b 100644
--- a/include/libcper/sections/cper-section.h
+++ b/include/libcper/sections/cper-section.h
@@ -15,7 +15,7 @@
EFI_GUID *Guid;
const char *ReadableName;
const char *ShortName;
- json_object *(*ToIR)(const void *);
+ json_object *(*ToIR)(const UINT8 *, UINT32);
void (*ToCPER)(json_object *, FILE *);
} CPER_SECTION_DEFINITION;
diff --git a/sections/cper-section-ampere.c b/sections/cper-section-ampere.c
index 5002a26..34d0829 100644
--- a/sections/cper-section-ampere.c
+++ b/sections/cper-section-ampere.c
@@ -5,8 +5,12 @@
#include <libcper/sections/cper-section-ampere.h>
//Converts the given processor-generic CPER section into JSON IR.
-json_object *cper_section_ampere_to_ir(const void *section)
+json_object *cper_section_ampere_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_AMPERE_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_AMPERE_ERROR_DATA *record = (EFI_AMPERE_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-arm.c b/sections/cper-section-arm.c
index 31fa9b0..6aa0b87 100644
--- a/sections/cper-section-arm.c
+++ b/sections/cper-section-arm.c
@@ -44,8 +44,11 @@
void ir_arm_unknown_register_to_cper(json_object *registers, FILE *out);
//Converts the given processor-generic CPER section into JSON IR.
-json_object *cper_section_arm_to_ir(const void *section)
+json_object *cper_section_arm_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_ARM_ERROR_RECORD)) {
+ return NULL;
+ }
EFI_ARM_ERROR_RECORD *record = (EFI_ARM_ERROR_RECORD *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-ccix-per.c b/sections/cper-section-ccix-per.c
index a4cab0c..d68f422 100644
--- a/sections/cper-section-ccix-per.c
+++ b/sections/cper-section-ccix-per.c
@@ -13,9 +13,18 @@
#include <libcper/sections/cper-section-ccix-per.h>
//Converts a single CCIX PER log CPER section into JSON IR.
-json_object *cper_section_ccix_per_to_ir(const void *section)
+json_object *cper_section_ccix_per_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_CCIX_PER_LOG_DATA)) {
+ return NULL;
+ }
+
EFI_CCIX_PER_LOG_DATA *ccix_error = (EFI_CCIX_PER_LOG_DATA *)section;
+
+ if (size < ccix_error->Length) {
+ return NULL;
+ }
+
json_object *section_ir = json_object_new_object();
ValidationTypes ui64Type = { UINT_64T,
.value.ui64 = ccix_error->ValidBits };
@@ -39,7 +48,7 @@
//CCIX PER Log.
if (isvalid_prop_to_ir(&ui64Type, 2)) {
//This is formatted as described in Section 7.3.2 of CCIX Base Specification (Rev 1.0).
- const char *cur_pos = (const char *)(ccix_error + 1);
+ const UINT8 *cur_pos = (const UINT8 *)(ccix_error + 1);
int remaining_length =
ccix_error->Length - sizeof(EFI_CCIX_PER_LOG_DATA);
if (remaining_length > 0) {
diff --git a/sections/cper-section-cxl-component.c b/sections/cper-section-cxl-component.c
index f1db9ad..cae152b 100644
--- a/sections/cper-section-cxl-component.c
+++ b/sections/cper-section-cxl-component.c
@@ -12,10 +12,20 @@
#include <libcper/sections/cper-section-cxl-component.h>
//Converts a single CXL component error CPER section into JSON IR.
-json_object *cper_section_cxl_component_to_ir(const void *section)
+json_object *cper_section_cxl_component_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_CXL_COMPONENT_EVENT_HEADER)) {
+ return NULL;
+ }
+
EFI_CXL_COMPONENT_EVENT_HEADER *cxl_error =
(EFI_CXL_COMPONENT_EVENT_HEADER *)section;
+ if (cxl_error->Length < sizeof(EFI_CXL_COMPONENT_EVENT_HEADER)) {
+ return NULL;
+ }
+ if (size < cxl_error->Length) {
+ return NULL;
+ }
json_object *section_ir = json_object_new_object();
//Length (bytes) for the entire structure.
@@ -63,20 +73,21 @@
//The specification for this is defined within the CXL Specification Section 8.2.9.1.
if (isvalid_prop_to_ir(&ui64Type, 2)) {
- const char *cur_pos = (const char *)(cxl_error + 1);
+ const UINT8 *cur_pos = (const UINT8 *)(cxl_error + 1);
int remaining_len = cxl_error->Length -
sizeof(EFI_CXL_COMPONENT_EVENT_HEADER);
if (remaining_len > 0) {
- json_object *event_log = json_object_new_object();
-
int32_t encoded_len = 0;
- char *encoded = base64_encode(
- (UINT8 *)cur_pos, remaining_len, &encoded_len);
+ char *encoded = base64_encode(cur_pos, remaining_len,
+ &encoded_len);
if (encoded == NULL) {
printf("Failed to allocate encode output buffer. \n");
+ json_object_put(section_ir);
return NULL;
}
+ json_object *event_log = json_object_new_object();
+
json_object_object_add(event_log, "data",
json_object_new_string_len(
encoded, encoded_len));
diff --git a/sections/cper-section-cxl-protocol.c b/sections/cper-section-cxl-protocol.c
index 4b5737b..1a9b33b 100644
--- a/sections/cper-section-cxl-protocol.c
+++ b/sections/cper-section-cxl-protocol.c
@@ -12,10 +12,21 @@
#include <libcper/sections/cper-section-cxl-protocol.h>
//Converts a single CXL protocol error CPER section into JSON IR.
-json_object *cper_section_cxl_protocol_to_ir(const void *section)
+json_object *cper_section_cxl_protocol_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_CXL_PROTOCOL_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_CXL_PROTOCOL_ERROR_DATA *cxl_protocol_error =
(EFI_CXL_PROTOCOL_ERROR_DATA *)section;
+
+ if (size < sizeof(EFI_CXL_PROTOCOL_ERROR_DATA) +
+ cxl_protocol_error->CxlDvsecLength +
+ cxl_protocol_error->CxlErrorLogLength) {
+ return NULL;
+ }
+
json_object *section_ir = json_object_new_object();
ValidationTypes ui64Type = {
UINT_64T, .value.ui64 = cxl_protocol_error->ValidBits
@@ -99,10 +110,8 @@
device_id, "slotNumber",
json_object_new_uint64(
cxl_protocol_error->DeviceId.SlotNumber));
- json_object_object_add(section_ir, "deviceID", device_id);
}
-
- char *encoded;
+ json_object_object_add(section_ir, "deviceID", device_id);
if (isvalid_prop_to_ir(&ui64Type, 3)) {
//Device serial & capability structure (if CXL 1.1 device).
@@ -115,6 +124,7 @@
}
}
+ char *encoded;
int32_t encoded_len = 0;
//The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
@@ -126,6 +136,8 @@
60, &encoded_len);
if (encoded == NULL) {
printf("Failed to allocate encode output buffer. \n");
+ json_object_put(section_ir);
+
return NULL;
}
json_object_object_add(section_ir, "capabilityStructure",
@@ -134,7 +146,7 @@
free(encoded);
}
- const char *cur_pos = (const char *)(cxl_protocol_error + 1);
+ const UINT8 *cur_pos = (const UINT8 *)(cxl_protocol_error + 1);
if (isvalid_prop_to_ir(&ui64Type, 5)) {
//CXL DVSEC & error log length.
@@ -147,10 +159,11 @@
//For CXL 1.1 host downstream ports, this is the "CXL DVSEC For Flex Bus Port" structure as in CXL 1.1 spec.
int32_t encoded_len = 0;
- encoded = base64_encode((UINT8 *)cur_pos,
+ encoded = base64_encode(cur_pos,
cxl_protocol_error->CxlDvsecLength,
&encoded_len);
if (encoded == NULL) {
+ json_object_put(section_ir);
return NULL;
}
json_object_object_add(section_ir, "cxlDVSEC",
@@ -178,6 +191,7 @@
if (encoded == NULL) {
printf("Failed to allocate encode output buffer. \n");
+ json_object_put(section_ir);
return NULL;
}
json_object_object_add(section_ir, "cxlErrorLog",
diff --git a/sections/cper-section-dmar-generic.c b/sections/cper-section-dmar-generic.c
index 7468d30..e745d2b 100644
--- a/sections/cper-section-dmar-generic.c
+++ b/sections/cper-section-dmar-generic.c
@@ -11,8 +11,12 @@
#include <libcper/sections/cper-section-dmar-generic.h>
//Converts a single generic DMAr CPER section into JSON IR.
-json_object *cper_section_dmar_generic_to_ir(const void *section)
+json_object *cper_section_dmar_generic_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_DMAR_GENERIC_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_DMAR_GENERIC_ERROR_DATA *firmware_error =
(EFI_DMAR_GENERIC_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-dmar-iommu.c b/sections/cper-section-dmar-iommu.c
index 99af77c..c411cf2 100644
--- a/sections/cper-section-dmar-iommu.c
+++ b/sections/cper-section-dmar-iommu.c
@@ -13,8 +13,12 @@
#include <libcper/sections/cper-section-dmar-iommu.h>
//Converts a single IOMMU specific DMAr CPER section into JSON IR.
-json_object *cper_section_dmar_iommu_to_ir(const void *section)
+json_object *cper_section_dmar_iommu_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_IOMMU_DMAR_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_IOMMU_DMAR_ERROR_DATA *iommu_error =
(EFI_IOMMU_DMAR_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-dmar-vtd.c b/sections/cper-section-dmar-vtd.c
index 16985a9..ad86293 100644
--- a/sections/cper-section-dmar-vtd.c
+++ b/sections/cper-section-dmar-vtd.c
@@ -13,8 +13,12 @@
#include <libcper/sections/cper-section-dmar-vtd.h>
//Converts a single VT-d specific DMAr CPER section into JSON IR.
-json_object *cper_section_dmar_vtd_to_ir(const void *section)
+json_object *cper_section_dmar_vtd_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_DIRECTED_IO_DMAR_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_DIRECTED_IO_DMAR_ERROR_DATA *vtd_error =
(EFI_DIRECTED_IO_DMAR_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-firmware.c b/sections/cper-section-firmware.c
index ebdc11f..78f04d0 100644
--- a/sections/cper-section-firmware.c
+++ b/sections/cper-section-firmware.c
@@ -11,8 +11,12 @@
#include <libcper/sections/cper-section-firmware.h>
//Converts a single firmware CPER section into JSON IR.
-json_object *cper_section_firmware_to_ir(const void *section)
+json_object *cper_section_firmware_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_FIRMWARE_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_FIRMWARE_ERROR_DATA *firmware_error =
(EFI_FIRMWARE_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-generic.c b/sections/cper-section-generic.c
index 7bbf56e..ec70b85 100644
--- a/sections/cper-section-generic.c
+++ b/sections/cper-section-generic.c
@@ -13,8 +13,12 @@
#include <libcper/sections/cper-section-generic.h>
//Converts the given processor-generic CPER section into JSON IR.
-json_object *cper_section_generic_to_ir(const void *section)
+json_object *cper_section_generic_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
(EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-ia32x64.c b/sections/cper-section-ia32x64.c
index f217612..bf7f565 100644
--- a/sections/cper-section-ia32x64.c
+++ b/sections/cper-section-ia32x64.c
@@ -21,7 +21,8 @@
cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check);
json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check);
json_object *cper_ia32x64_processor_context_info_to_ir(
- EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos);
+ EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
+ UINT32 *remaining_size);
json_object *
cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers);
json_object *
@@ -43,10 +44,15 @@
//////////////////
//Converts the IA32/x64 error section described in the given descriptor into intermediate format.
-json_object *cper_section_ia32x64_to_ir(const void *section)
+json_object *cper_section_ia32x64_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD)) {
+ return NULL;
+ }
EFI_IA32_X64_PROCESSOR_ERROR_RECORD *record =
(EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)section;
+ UINT32 remaining_size =
+ size - sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD);
json_object *record_ir = json_object_new_object();
//Validation bits.
@@ -89,16 +95,34 @@
EFI_IA32_X64_PROCESS_ERROR_INFO *current_error_info =
(EFI_IA32_X64_PROCESS_ERROR_INFO *)(record + 1);
json_object *error_info_array = json_object_new_array();
+ if (remaining_size < (processor_error_info_num *
+ sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO))) {
+ json_object_put(error_info_array);
+ json_object_put(record_ir);
+ printf("Invalid CPER file: Invalid processor error info num.\n");
+ return NULL;
+ }
+
for (int i = 0; i < processor_error_info_num; i++) {
json_object_array_add(error_info_array,
cper_ia32x64_processor_error_info_to_ir(
current_error_info));
current_error_info++;
}
+ remaining_size -= processor_error_info_num *
+ sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO);
+
json_object_object_add(record_ir, "processorErrorInfo",
error_info_array);
//Processor context information, of the amount described above.
+ if (remaining_size < (processor_context_info_num *
+ sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO))) {
+ json_object_put(error_info_array);
+ json_object_put(record_ir);
+ printf("Invalid CPER file: Invalid processor context info num.\n");
+ return NULL;
+ }
EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *current_context_info =
(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)current_error_info;
void *cur_pos = (void *)current_context_info;
@@ -106,11 +130,14 @@
for (int i = 0; i < processor_context_info_num; i++) {
json_object_array_add(context_info_array,
cper_ia32x64_processor_context_info_to_ir(
- current_context_info, &cur_pos));
+ current_context_info, &cur_pos,
+ &remaining_size));
current_context_info =
(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)cur_pos;
+
//The context array is a non-fixed size, pointer is shifted within the above function.
}
+
json_object_object_add(record_ir, "processorContextInfo",
context_info_array);
@@ -424,13 +451,18 @@
//Converts a single IA32/x64 processor context info entry into JSON IR format.
json_object *cper_ia32x64_processor_context_info_to_ir(
- EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos)
+ EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
+ UINT32 *remaining_size)
{
+ if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
+ return NULL;
+ }
+ *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
json_object *context_info_ir = json_object_new_object();
//Register context type.
json_object *context_type = integer_to_readable_pair(
- context_info->RegisterType, 8,
+ context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
json_object_object_add(context_info_ir, "registerContextType",
@@ -449,21 +481,34 @@
//Register array.
json_object *register_array = NULL;
if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
+ if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
+ json_object_put(context_info_ir);
+ return NULL;
+ }
EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
(EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
register_array =
cper_ia32x64_register_32bit_to_ir(register_state);
*cur_pos = (void *)(register_state + 1);
+ *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
} else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
+ if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
+ json_object_put(context_info_ir);
+ return NULL;
+ }
EFI_CONTEXT_X64_REGISTER_STATE *register_state =
(EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
register_array =
cper_ia32x64_register_64bit_to_ir(register_state);
*cur_pos = (void *)(register_state + 1);
+ *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
} else {
//No parseable data, just dump as base64 and shift the head to the next item.
*cur_pos = (void *)(context_info + 1);
-
+ if (*remaining_size < context_info->ArraySize) {
+ json_object_put(context_info_ir);
+ return NULL;
+ }
int32_t encoded_len = 0;
char *encoded = base64_encode((UINT8 *)*cur_pos,
context_info->ArraySize,
@@ -480,6 +525,7 @@
*cur_pos =
(void *)(((char *)*cur_pos) + context_info->ArraySize);
+ *remaining_size -= context_info->ArraySize;
}
json_object_object_add(context_info_ir, "registerArray",
register_array);
diff --git a/sections/cper-section-ipf.c b/sections/cper-section-ipf.c
index a50cfab..2cf6f13 100644
--- a/sections/cper-section-ipf.c
+++ b/sections/cper-section-ipf.c
@@ -15,8 +15,12 @@
json_object *cper_ipf_mod_error_to_ir(EFI_IPF_MOD_ERROR_INFO *mod_error);
//Converts a single Intel IPF error CPER section into JSON IR.
-json_object *cper_section_ipf_to_ir(const void *section)
+json_object *cper_section_ipf_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_IPF_ERROR_INFO_HEADER)) {
+ return NULL;
+ }
+
EFI_IPF_ERROR_INFO_HEADER *ipf_error =
(EFI_IPF_ERROR_INFO_HEADER *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-memory.c b/sections/cper-section-memory.c
index c5a2094..b58bf82 100644
--- a/sections/cper-section-memory.c
+++ b/sections/cper-section-memory.c
@@ -11,8 +11,13 @@
#include <libcper/sections/cper-section-memory.h>
//Converts a single memory error CPER section into JSON IR.
-json_object *cper_section_platform_memory_to_ir(const void *section)
+json_object *cper_section_platform_memory_to_ir(const UINT8 *section,
+ UINT32 size)
{
+ if (size < sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error =
(EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
@@ -166,8 +171,13 @@
}
//Converts a single memory error 2 CPER section into JSON IR.
-json_object *cper_section_platform_memory2_to_ir(const void *section)
+json_object *cper_section_platform_memory2_to_ir(const UINT8 *section,
+ UINT32 size)
{
+ if (size < sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error =
(EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-nvidia.c b/sections/cper-section-nvidia.c
index 8b211ea..83c6083 100644
--- a/sections/cper-section-nvidia.c
+++ b/sections/cper-section-nvidia.c
@@ -12,9 +12,19 @@
#include <libcper/sections/cper-section-nvidia.h>
//Converts a single NVIDIA CPER section into JSON IR.
-json_object *cper_section_nvidia_to_ir(const void *section)
+json_object *cper_section_nvidia_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_NVIDIA_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_NVIDIA_ERROR_DATA *nvidia_error = (EFI_NVIDIA_ERROR_DATA *)section;
+ if (size < sizeof(EFI_NVIDIA_ERROR_DATA) +
+ nvidia_error->NumberRegs *
+ sizeof(EFI_NVIDIA_REGISTER_DATA)) {
+ return NULL;
+ }
+
json_object *section_ir = json_object_new_object();
json_object_object_add(section_ir, "signature",
diff --git a/sections/cper-section-pci-bus.c b/sections/cper-section-pci-bus.c
index 5564c21..70b5a2c 100644
--- a/sections/cper-section-pci-bus.c
+++ b/sections/cper-section-pci-bus.c
@@ -12,8 +12,12 @@
#include <libcper/sections/cper-section-pci-bus.h>
//Converts a single PCI/PCI-X bus CPER section into JSON IR.
-json_object *cper_section_pci_bus_to_ir(const void *section)
+json_object *cper_section_pci_bus_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_PCI_PCIX_BUS_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_PCI_PCIX_BUS_ERROR_DATA *bus_error =
(EFI_PCI_PCIX_BUS_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
diff --git a/sections/cper-section-pci-dev.c b/sections/cper-section-pci-dev.c
index adc54a0..9f89494 100644
--- a/sections/cper-section-pci-dev.c
+++ b/sections/cper-section-pci-dev.c
@@ -11,10 +11,21 @@
#include <libcper/sections/cper-section-pci-dev.h>
//Converts a single PCI/PCI-X device CPER section into JSON IR.
-json_object *cper_section_pci_dev_to_ir(const void *section)
+json_object *cper_section_pci_dev_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_PCI_PCIX_DEVICE_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_PCI_PCIX_DEVICE_ERROR_DATA *dev_error =
(EFI_PCI_PCIX_DEVICE_ERROR_DATA *)section;
+
+ if (size < sizeof(EFI_PCI_PCIX_DEVICE_ERROR_DATA) +
+ ((dev_error->MemoryNumber + dev_error->IoNumber) *
+ sizeof(EFI_PCI_PCIX_DEVICE_ERROR_DATA_REGISTER))) {
+ return NULL;
+ }
+
json_object *section_ir = json_object_new_object();
//Validation bits.
diff --git a/sections/cper-section-pcie.c b/sections/cper-section-pcie.c
index 5e83f9d..93d6331 100644
--- a/sections/cper-section-pcie.c
+++ b/sections/cper-section-pcie.c
@@ -24,8 +24,12 @@
};
//Converts a single PCIe CPER section into JSON IR.
-json_object *cper_section_pcie_to_ir(const void *section)
+json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size)
{
+ if (size < sizeof(EFI_PCIE_ERROR_DATA)) {
+ return NULL;
+ }
+
EFI_PCIE_ERROR_DATA *pcie_error = (EFI_PCIE_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();