Fix bugs appearing from fuzzing.
diff --git a/generator/sections/gen-section-cxl-protocol.c b/generator/sections/gen-section-cxl-protocol.c
index 64326f9..85457ce 100644
--- a/generator/sections/gen-section-cxl-protocol.c
+++ b/generator/sections/gen-section-cxl-protocol.c
@@ -45,6 +45,13 @@
reserved = (UINT32*)(bytes + 112);
*reserved = 0; //Reserved bytes 112-115.
+ //If the device is a host downstream port, serial/capability structure is invalid.
+ if (cxl_agent_type != 0)
+ {
+ for (int i=0; i<68; i++)
+ *(bytes + 40 + i) = 0; //Device serial & capability structure.
+ }
+
//Set expected values.
UINT16* dvsec_length_field = (UINT16*)(bytes + 108);
UINT16* error_log_len_field = (UINT16*)(bytes + 110);
diff --git a/generator/sections/gen-section-dmar.c b/generator/sections/gen-section-dmar.c
index d0bbb5e..cb732cc 100644
--- a/generator/sections/gen-section-dmar.c
+++ b/generator/sections/gen-section-dmar.c
@@ -44,6 +44,12 @@
//Set reserved areas to zero.
for (int i=0; i<12; i++)
*(bytes + 36 + i) = 0; //Reserved bytes 36-47.
+ UINT8* fault_record = bytes + 48;
+ UINT32* reserved = (UINT32*)(fault_record);
+ *reserved &= ~0xFFF; //First 12 bits of fault record.
+ reserved = (UINT32*)(fault_record + 10);
+ *reserved &= ~0x1FFF; //Bits 80-92 of fault record.
+ *(fault_record + 15) &= 0x7; //Very last bit of fault record.
//Set return values, exit.
*location = bytes;
@@ -60,7 +66,7 @@
//Set reserved areas to zero.
for (int i=0; i<7; i++)
- *(bytes + 1 + i) + 0; //Reserved bytes 1 to 7.
+ *(bytes + 1 + i) = 0; //Reserved bytes 1 to 7.
UINT64* reserved = (UINT64*)(bytes + 24);
*reserved = 0; //Reserved bytes 24-31.
for (int i=0; i<16; i++)
diff --git a/generator/sections/gen-section-firmware.c b/generator/sections/gen-section-firmware.c
index 09c47ff..5b39fa1 100644
--- a/generator/sections/gen-section-firmware.c
+++ b/generator/sections/gen-section-firmware.c
@@ -18,8 +18,8 @@
UINT8* bytes = generate_random_bytes(size);
//Set reserved areas to zero.
- for (int i=0; i<7; i++)
- *(bytes + 2 + i) = 0; //Reserved bytes 2-9.
+ for (int i=0; i<6; i++)
+ *(bytes + 2 + i) = 0; //Reserved bytes 2-7.
//Set expected values.
*(bytes + 1) = 2; //Revision, referenced version of spec is 2.
diff --git a/generator/sections/gen-section-pci-bus.c b/generator/sections/gen-section-pci-bus.c
index 9afd9ad..cbe5b81 100644
--- a/generator/sections/gen-section-pci-bus.c
+++ b/generator/sections/gen-section-pci-bus.c
@@ -14,7 +14,7 @@
size_t generate_section_pci_bus(void** location)
{
//Create random bytes.
- int size = 208;
+ int size = 72;
UINT8* bytes = generate_random_bytes(size);
//Set reserved areas to zero.
diff --git a/sections/cper-section-ccix-per.c b/sections/cper-section-ccix-per.c
index 072c5d2..d295017 100644
--- a/sections/cper-section-ccix-per.c
+++ b/sections/cper-section-ccix-per.c
@@ -32,7 +32,7 @@
//CCIX PER Log.
//This is formatted as described in Section 7.3.2 of CCIX Base Specification (Rev 1.0).
unsigned char* cur_pos = (unsigned char*)(ccix_error + 1);
- int remaining_length = ccix_error->Length - sizeof(ccix_error);
+ int remaining_length = ccix_error->Length - sizeof(EFI_CCIX_PER_LOG_DATA);
if (remaining_length > 0)
{
char* encoded = b64_encode(cur_pos, remaining_length);
@@ -67,7 +67,7 @@
//Write CCIX PER log itself to stream.
json_object* encoded = json_object_object_get(section, "ccixPERLog");
UINT8* decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
- fwrite(decoded, section_cper->Length - sizeof(section_cper), 1, out);
+ fwrite(decoded, section_cper->Length - sizeof(EFI_CCIX_PER_LOG_DATA), 1, out);
fflush(out);
//Free resources.
diff --git a/sections/cper-section-ccix-per.h b/sections/cper-section-ccix-per.h
index 0fbefe5..f74f952 100644
--- a/sections/cper-section-ccix-per.h
+++ b/sections/cper-section-ccix-per.h
@@ -15,7 +15,7 @@
UINT8 CcixSourceId;
UINT8 CcixPortId;
UINT16 Reserved;
-} EFI_CCIX_PER_LOG_DATA;
+} __attribute__((packed, aligned(1))) EFI_CCIX_PER_LOG_DATA;
json_object* cper_section_ccix_per_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
void ir_section_ccix_per_to_cper(json_object* section, FILE* out);
diff --git a/sections/cper-section-cxl-component.c b/sections/cper-section-cxl-component.c
index 934a1cf..15454a2 100644
--- a/sections/cper-section-cxl-component.c
+++ b/sections/cper-section-cxl-component.c
@@ -90,8 +90,9 @@
fflush(out);
//CXL component event log, decoded from base64.
- json_object* encoded = json_object_object_get(section, "cxlComponentEventLog");
- int log_length = section_cper->Length - sizeof(section_cper);
+ json_object* event_log = json_object_object_get(section, "cxlComponentEventLog");
+ json_object* encoded = json_object_object_get(event_log, "data");
+ int log_length = section_cper->Length - sizeof(EFI_CXL_COMPONENT_EVENT_HEADER);
char* decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
fwrite(decoded, log_length, 1, out);
fflush(out);
diff --git a/sections/cper-section-cxl-component.h b/sections/cper-section-cxl-component.h
index e9cbfd5..e0a585e 100644
--- a/sections/cper-section-cxl-component.h
+++ b/sections/cper-section-cxl-component.h
@@ -20,14 +20,14 @@
UINT64 Resv1 : 3;
UINT64 SlotNumber : 13;
UINT64 Resv2 : 8;
-} EFI_CXL_DEVICE_ID_INFO;
+} __attribute__((packed, aligned(1))) EFI_CXL_DEVICE_ID_INFO;
typedef struct {
UINT32 Length;
UINT64 ValidBits;
EFI_CXL_DEVICE_ID_INFO DeviceId;
UINT64 DeviceSerial;
-} EFI_CXL_COMPONENT_EVENT_HEADER;
+} __attribute__((packed, aligned(1))) EFI_CXL_COMPONENT_EVENT_HEADER;
json_object* cper_section_cxl_component_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
void ir_section_cxl_component_to_cper(json_object* section, FILE* out);
diff --git a/sections/cper-section-cxl-protocol.c b/sections/cper-section-cxl-protocol.c
index f9b0550..b3334a3 100644
--- a/sections/cper-section-cxl-protocol.c
+++ b/sections/cper-section-cxl-protocol.c
@@ -107,7 +107,7 @@
{
EFI_CXL_PROTOCOL_ERROR_DATA* section_cper =
(EFI_CXL_PROTOCOL_ERROR_DATA*)calloc(1, sizeof(EFI_CXL_PROTOCOL_ERROR_DATA));
-
+
//Validation bits.
section_cper->ValidBits = ir_to_bitfield(json_object_object_get(section, "validationBits"),
7, CXL_PROTOCOL_ERROR_VALID_BITFIELD_NAMES);
diff --git a/sections/cper-section-cxl-protocol.h b/sections/cper-section-cxl-protocol.h
index 33b45d9..a64b83e 100644
--- a/sections/cper-section-cxl-protocol.h
+++ b/sections/cper-section-cxl-protocol.h
@@ -48,7 +48,7 @@
UINT16 CxlDvsecLength;
UINT16 CxlErrorLogLength;
UINT32 Reserved;
-} EFI_CXL_PROTOCOL_ERROR_DATA;
+} __attribute__((packed, aligned(1))) EFI_CXL_PROTOCOL_ERROR_DATA;
json_object* cper_section_cxl_protocol_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
void ir_section_cxl_protocol_to_cper(json_object* section, FILE* out);
diff --git a/sections/cper-section-dmar-generic.c b/sections/cper-section-dmar-generic.c
index 58e002c..faeefa8 100644
--- a/sections/cper-section-dmar-generic.c
+++ b/sections/cper-section-dmar-generic.c
@@ -67,7 +67,7 @@
section_cper->FaultReason = (UINT8)readable_pair_to_integer(json_object_object_get(section, "faultReason"));
section_cper->AccessType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "accessType"));
section_cper->AddressType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "addressType"));
- section_cper->ArchType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "archType"));
+ section_cper->ArchType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "architectureType"));
section_cper->DeviceAddr = json_object_get_uint64(json_object_object_get(section, "deviceAddress"));
//Write to stream, free resources.
diff --git a/sections/cper-section-dmar-vtd.c b/sections/cper-section-dmar-vtd.c
index b57d1ba..cfaace7 100644
--- a/sections/cper-section-dmar-vtd.c
+++ b/sections/cper-section-dmar-vtd.c
@@ -19,7 +19,9 @@
json_object* section_ir = json_object_new_object();
//Version, revision and OEM ID, as defined in the VT-d architecture.
- UINT64 oem_id = (vtd_error->OemId[0] << 16) + (vtd_error->OemId[1] << 8) + vtd_error->OemId[2];
+ UINT64 oem_id = 0;
+ for (int i=0; i<6; i++)
+ oem_id |= (UINT64)vtd_error->OemId[i] << (i * 8);
json_object_object_add(section_ir, "version", json_object_new_int(vtd_error->Version));
json_object_object_add(section_ir, "revision", json_object_new_int(vtd_error->Revision));
json_object_object_add(section_ir, "oemID", json_object_new_uint64(oem_id));
@@ -82,15 +84,17 @@
//OEM ID.
UINT64 oem_id = json_object_get_uint64(json_object_object_get(section, "oemID"));
- section_cper->OemId[0] = oem_id >> 16;
- section_cper->OemId[1] = (oem_id >> 8) & 0xFF;
- section_cper->OemId[1] = oem_id & 0xFF;
+ for (int i=0; i<6; i++)
+ section_cper->OemId[i] = (oem_id >> (i * 8)) & 0xFF;
//Registers & basic numeric fields.
section_cper->Version = (UINT8)json_object_get_int(json_object_object_get(section, "version"));
section_cper->Revision = (UINT8)json_object_get_int(json_object_object_get(section, "revision"));
section_cper->Capability = json_object_get_uint64(json_object_object_get(section, "capabilityRegister"));
section_cper->CapabilityEx = json_object_get_uint64(json_object_object_get(section, "extendedCapabilityRegister"));
+ section_cper->GlobalCommand = json_object_get_uint64(json_object_object_get(section, "globalCommandRegister"));
+ section_cper->GlobalStatus = json_object_get_uint64(json_object_object_get(section, "globalStatusRegister"));
+ section_cper->FaultStatus = json_object_get_uint64(json_object_object_get(section, "faultStatusRegister"));
//Fault record.
json_object* fault_record = json_object_object_get(section, "faultRecord");
diff --git a/sections/cper-section-firmware.c b/sections/cper-section-firmware.c
index c7c91f5..5e17e90 100644
--- a/sections/cper-section-firmware.c
+++ b/sections/cper-section-firmware.c
@@ -44,7 +44,7 @@
//Record fields.
section_cper->ErrorType = readable_pair_to_integer(json_object_object_get(section, "errorRecordType"));
section_cper->Revision = json_object_get_int(json_object_object_get(section, "revision"));
- section_cper->RecordId = json_object_get_uint64(json_object_object_get(section, "revision"));
+ section_cper->RecordId = json_object_get_uint64(json_object_object_get(section, "recordID"));
string_to_guid(§ion_cper->RecordIdGuid,
json_object_get_string(json_object_object_get(section, "recordIDGUID")));
diff --git a/sections/cper-section-pci-bus.c b/sections/cper-section-pci-bus.c
index 0b0c297..0065192 100644
--- a/sections/cper-section-pci-bus.c
+++ b/sections/cper-section-pci-bus.c
@@ -5,6 +5,7 @@
* Author: Lawrence.Tang@arm.com
**/
#include <stdio.h>
+#include <string.h>
#include "json.h"
#include "../edk/Cper.h"
#include "../cper-utils.h"
@@ -70,12 +71,14 @@
section_cper->BusId = bus_number + (segment_number << 8);
//Remaining fields.
+ UINT64 pcix_command = (UINT64)0x1 << 56;
+ const char* bus_command = json_object_get_string(json_object_object_get(section, "busCommandType"));
section_cper->Type = (UINT16)readable_pair_to_integer(json_object_object_get(section, "errorType"));
section_cper->BusAddress = json_object_get_uint64(json_object_object_get(section, "busAddress"));
section_cper->BusData = json_object_get_uint64(json_object_object_get(section, "busData"));
- section_cper->BusCommand = json_object_get_string(json_object_object_get(section, "busCommand")) == "PCI" ? 0 : 1;
- section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID"));
- section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID"));
+ section_cper->BusCommand = strcmp(bus_command, "PCI") == 0 ? 0 : pcix_command;
+ section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "busRequestorID"));
+ section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "busCompleterID"));
section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID"));
//Write to stream, free resources.
diff --git a/sections/cper-section-pci-dev.c b/sections/cper-section-pci-dev.c
index cac363d..cae0c2b 100644
--- a/sections/cper-section-pci-dev.c
+++ b/sections/cper-section-pci-dev.c
@@ -88,7 +88,7 @@
section_cper->IoNumber = (UINT32)json_object_get_uint64(json_object_object_get(section, "ioNumber"));
//Write header out to stream, free it.
- fwrite(§ion_cper, sizeof(section_cper), 1, out);
+ fwrite(section_cper, sizeof(EFI_PCI_PCIX_DEVICE_ERROR_DATA), 1, out);
fflush(out);
free(section_cper);