Fix microcode detection

closes #194
This commit is contained in:
vit9696 2020-02-08 22:05:33 +03:00
parent 1dccf3f15a
commit 6fdc69415b

View File

@ -4310,6 +4310,11 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
dataSize = INTEL_MICROCODE_REAL_DATA_SIZE_ON_ZERO; dataSize = INTEL_MICROCODE_REAL_DATA_SIZE_ON_ZERO;
} }
// Cross check DataSize and TotalSize
if (ucodeHeader->TotalSize < sizeof(INTEL_MICROCODE_HEADER) + dataSize) {
return U_INVALID_MICROCODE;
}
// Recalculate the whole microcode checksum // Recalculate the whole microcode checksum
UByteArray tempMicrocode = microcode; UByteArray tempMicrocode = microcode;
INTEL_MICROCODE_HEADER* tempUcodeHeader = (INTEL_MICROCODE_HEADER*)(tempMicrocode.data()); INTEL_MICROCODE_HEADER* tempUcodeHeader = (INTEL_MICROCODE_HEADER*)(tempMicrocode.data());
@ -4320,10 +4325,16 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
// Construct header, body and tail // Construct header, body and tail
UByteArray header = microcode.left(sizeof(INTEL_MICROCODE_HEADER)); UByteArray header = microcode.left(sizeof(INTEL_MICROCODE_HEADER));
UByteArray body = microcode.mid(sizeof(INTEL_MICROCODE_HEADER), dataSize); UByteArray body = microcode.mid(sizeof(INTEL_MICROCODE_HEADER), dataSize);
UByteArray tail = microcode.mid(sizeof(INTEL_MICROCODE_HEADER) + dataSize); UByteArray tail;
// Check if the tail is present
if (ucodeHeader->TotalSize > sizeof(INTEL_MICROCODE_HEADER) + dataSize) {
tail = microcode.mid(sizeof(INTEL_MICROCODE_HEADER) + dataSize, ucodeHeader->TotalSize - (sizeof(INTEL_MICROCODE_HEADER) + dataSize));
}
// Check if we have extended header in the tail // Check if we have extended header in the tail
UString extendedHeaderInfo; UString extendedHeaderInfo;
bool msgUnknownOrDamagedMicrocodeTail = false;
if ((UINT32)tail.size() >= sizeof(INTEL_MICROCODE_EXTENDED_HEADER)) { if ((UINT32)tail.size() >= sizeof(INTEL_MICROCODE_EXTENDED_HEADER)) {
const INTEL_MICROCODE_EXTENDED_HEADER* extendedHeader = (const INTEL_MICROCODE_EXTENDED_HEADER*)tail.constData(); const INTEL_MICROCODE_EXTENDED_HEADER* extendedHeader = (const INTEL_MICROCODE_EXTENDED_HEADER*)tail.constData();
@ -4339,7 +4350,7 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
// We have more than 0 entries and they are all in the tail // We have more than 0 entries and they are all in the tail
if (extendedReservedBytesValid if (extendedReservedBytesValid
&& extendedHeader->EntryCount > 0 && extendedHeader->EntryCount > 0
&& (UINT32)tail.size() >= sizeof(INTEL_MICROCODE_EXTENDED_HEADER) + extendedHeader->EntryCount * sizeof(INTEL_MICROCODE_EXTENDED_HEADER_ENTRY)) { && (UINT32)tail.size() == sizeof(INTEL_MICROCODE_EXTENDED_HEADER) + extendedHeader->EntryCount * sizeof(INTEL_MICROCODE_EXTENDED_HEADER_ENTRY)) {
// Recalculate extended header checksum // Recalculate extended header checksum
INTEL_MICROCODE_EXTENDED_HEADER* tempExtendedHeader = (INTEL_MICROCODE_EXTENDED_HEADER*)(tempMicrocode.data() + sizeof(INTEL_MICROCODE_HEADER) + dataSize); INTEL_MICROCODE_EXTENDED_HEADER* tempExtendedHeader = (INTEL_MICROCODE_EXTENDED_HEADER*)(tempMicrocode.data() + sizeof(INTEL_MICROCODE_HEADER) + dataSize);
tempExtendedHeader->Checksum = 0; tempExtendedHeader->Checksum = 0;
@ -4367,16 +4378,23 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
+ (entry->Checksum == entryCalculated ? UString("valid") : usprintf("invalid, should be %08Xh", entryCalculated)); + (entry->Checksum == entryCalculated ? UString("valid") : usprintf("invalid, should be %08Xh", entryCalculated));
} }
} }
else {
msgUnknownOrDamagedMicrocodeTail = true;
}
} }
else if (tail.size() != 0) {
msgUnknownOrDamagedMicrocodeTail = true;
}
// Get microcode binary
UByteArray microcodeBinary = microcode.left(ucodeHeader->TotalSize);
// Add info // Add info
UString name("Intel microcode"); UString name("Intel microcode");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\n" UString info = usprintf("Full size: %Xh (%u)\nHeader size: 0h (0u)\nBody size: %Xh (%u)\nTail size: 0h (0u)\n"
"Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nCPU flags: %02Xh\nChecksum: %08Xh, ", "Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nCPU flags: %02Xh\nChecksum: %08Xh, ",
dataSize, dataSize, microcodeBinary.size(), microcodeBinary.size(),
header.size(), header.size(), microcodeBinary.size(), microcodeBinary.size(),
body.size(), body.size(),
tail.size(), tail.size(),
ucodeHeader->DateDay, ucodeHeader->DateDay,
ucodeHeader->DateMonth, ucodeHeader->DateMonth,
ucodeHeader->DateYear, ucodeHeader->DateYear,
@ -4388,9 +4406,11 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
+ extendedHeaderInfo; + extendedHeaderInfo;
// Add tree item // Add tree item
index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, tail, Fixed, parent); index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, UByteArray(), microcodeBinary, UByteArray(), Fixed, parent);
if (msgInvalidChecksum) if (msgInvalidChecksum)
msg(usprintf("%s: invalid microcode checksum %08Xh, should be %08Xh", __FUNCTION__, ucodeHeader->Checksum, calculated), index); msg(usprintf("%s: invalid microcode checksum %08Xh, should be %08Xh", __FUNCTION__, ucodeHeader->Checksum, calculated), index);
if (msgUnknownOrDamagedMicrocodeTail)
msg(usprintf("%s: extended header of size %Xh (%u) found, but it's damaged or has unknown format", __FUNCTION__, tail.size(), tail.size()), index);
// No need to parse the body further for now // No need to parse the body further for now
return U_SUCCESS; return U_SUCCESS;