Skip to content

Commit d61d759

Browse files
committed
Make sure to wrap all uses of kaitai::kstream into try-catch blocks
1 parent 7ef3719 commit d61d759

File tree

1 file changed

+101
-96
lines changed

1 file changed

+101
-96
lines changed

common/ffsparser.cpp

Lines changed: 101 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -953,111 +953,116 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
953953
}
954954
}
955955
else if (itemType == Types::InsydeFlashDeviceMapStore) {
956-
UByteArray fdm = data.mid(itemOffset, itemSize);
957-
umemstream is(fdm.constData(), fdm.size());
958-
kaitai::kstream ks(&is);
959-
insyde_fdm_t parsed(&ks);
960-
UINT32 storeSize = (UINT32)fdm.size();
961-
962-
// Construct header and body
963-
UByteArray header = fdm.left(parsed.data_offset());
964-
UByteArray body = fdm.mid(header.size(), storeSize - header.size());
965-
966-
// Add info
967-
UString name = UString("Insyde H2O FlashDeviceMap");
968-
UString info = usprintf("Signature: HFDM\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nData offset: %Xh\nEntry size: %Xh (%u)\nEntry format: %02Xh\nRevision: %02Xh\nExtension count: %u\nFlash descriptor base address: %08Xh\nChecksum: %02Xh",
969-
storeSize, storeSize,
970-
(UINT32)header.size(), (UINT32)header.size(),
971-
(UINT32)body.size(), (UINT32)body.size(),
972-
parsed.data_offset(),
973-
parsed.entry_size(), parsed.entry_size(),
974-
parsed.entry_format(),
975-
parsed.revision(),
976-
parsed.num_extensions(),
977-
(UINT32)parsed.fd_base_address(),
978-
parsed.checksum());
979-
980-
// Check header checksum
981-
{
982-
UByteArray tempHeader = data.mid(itemOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_HEADER));
983-
INSYDE_FLASH_DEVICE_MAP_HEADER* tempFdmHeader = (INSYDE_FLASH_DEVICE_MAP_HEADER*)tempHeader.data();
984-
tempFdmHeader->Checksum = 0;
985-
UINT8 calculated = calculateChecksum8((const UINT8*)tempFdmHeader, (UINT32)tempHeader.size());
986-
if (calculated == parsed.checksum()) {
987-
info += UString(", valid");
988-
}
989-
else {
990-
info += usprintf(", invalid, should be %02Xh", calculated);
991-
}
992-
}
993-
994-
// Add board IDs
995-
if (!parsed._is_null_board_ids()) {
996-
info += usprintf("\nRegion index: %Xh\nBoardId Count: %u",
997-
parsed.board_ids()->region_index(),
998-
parsed.board_ids()->num_board_ids());
999-
UINT32 i = 0;
1000-
for (const auto & boardId : *parsed.board_ids()->board_ids()) {
1001-
info += usprintf("\nBoardId #%u: %" PRIX64 "\n", i++, boardId);
1002-
}
1003-
}
1004-
1005-
// Add header tree item
1006-
UModelIndex headerIndex = model->addItem(headerSize + itemOffset, Types::InsydeFlashDeviceMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
1007-
1008-
// Add entries
1009-
UINT32 entryOffset = parsed.data_offset();
1010-
bool protectedRangeFound = false;
1011-
for (const auto & entry : *parsed.entries()->entries()) {
1012-
const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str());
1013-
name = insydeFlashDeviceMapEntryTypeGuidToUString(guid);
1014-
UString text;
1015-
header = data.mid(itemOffset + entryOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_ENTRY));
1016-
body = data.mid(itemOffset + entryOffset + header.size(), parsed.entry_size() - header.size());
1017-
956+
try {
957+
UByteArray fdm = data.mid(itemOffset, itemSize);
958+
umemstream is(fdm.constData(), fdm.size());
959+
kaitai::kstream ks(&is);
960+
insyde_fdm_t parsed(&ks);
961+
UINT32 storeSize = (UINT32)fdm.size();
962+
963+
// Construct header and body
964+
UByteArray header = fdm.left(parsed.data_offset());
965+
UByteArray body = fdm.mid(header.size(), storeSize - header.size());
966+
1018967
// Add info
1019-
UINT32 entrySize = (UINT32)header.size() + (UINT32)body.size();
1020-
info = UString("Region type: ") + guidToUString(guid, false) + "\n";
1021-
info += UString("Region id: ");
1022-
for (UINT8 i = 0; i < 16; i++) {
1023-
info += usprintf("%02X", *(const UINT8*)(entry->region_id().c_str() + i));
968+
UString name = UString("Insyde H2O FlashDeviceMap");
969+
UString info = usprintf("Signature: HFDM\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nData offset: %Xh\nEntry size: %Xh (%u)\nEntry format: %02Xh\nRevision: %02Xh\nExtension count: %u\nFlash descriptor base address: %08Xh\nChecksum: %02Xh",
970+
storeSize, storeSize,
971+
(UINT32)header.size(), (UINT32)header.size(),
972+
(UINT32)body.size(), (UINT32)body.size(),
973+
parsed.data_offset(),
974+
parsed.entry_size(), parsed.entry_size(),
975+
parsed.entry_format(),
976+
parsed.revision(),
977+
parsed.num_extensions(),
978+
(UINT32)parsed.fd_base_address(),
979+
parsed.checksum());
980+
981+
// Check header checksum
982+
{
983+
UByteArray tempHeader = data.mid(itemOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_HEADER));
984+
INSYDE_FLASH_DEVICE_MAP_HEADER* tempFdmHeader = (INSYDE_FLASH_DEVICE_MAP_HEADER*)tempHeader.data();
985+
tempFdmHeader->Checksum = 0;
986+
UINT8 calculated = calculateChecksum8((const UINT8*)tempFdmHeader, (UINT32)tempHeader.size());
987+
if (calculated == parsed.checksum()) {
988+
info += UString(", valid");
989+
}
990+
else {
991+
info += usprintf(", invalid, should be %02Xh", calculated);
992+
}
1024993
}
1025-
info += usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRegion address: %08Xh\nRegion size: %08Xh\nAttributes: %08Xh",
1026-
entrySize, entrySize,
1027-
(UINT32)header.size(), (UINT32)header.size(),
1028-
(UINT32)body.size(), (UINT32)body.size(),
1029-
(UINT32)entry->region_base(),
1030-
(UINT32)entry->region_size(),
1031-
entry->attributes());
1032-
1033-
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) {
1034-
if (!protectedRangeFound) {
1035-
securityInfo += usprintf("Insyde Flash Device Map found at base %08Xh\nProtected ranges:\n", model->base(headerIndex));
1036-
protectedRangeFound = true;
994+
995+
// Add board IDs
996+
if (!parsed._is_null_board_ids()) {
997+
info += usprintf("\nRegion index: %Xh\nBoardId Count: %u",
998+
parsed.board_ids()->region_index(),
999+
parsed.board_ids()->num_board_ids());
1000+
UINT32 i = 0;
1001+
for (const auto & boardId : *parsed.board_ids()->board_ids()) {
1002+
info += usprintf("\nBoardId #%u: %" PRIX64 "\n", i++, boardId);
1003+
}
1004+
}
1005+
1006+
// Add header tree item
1007+
UModelIndex headerIndex = model->addItem(headerSize + itemOffset, Types::InsydeFlashDeviceMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
1008+
1009+
// Add entries
1010+
UINT32 entryOffset = parsed.data_offset();
1011+
bool protectedRangeFound = false;
1012+
for (const auto & entry : *parsed.entries()->entries()) {
1013+
const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str());
1014+
name = insydeFlashDeviceMapEntryTypeGuidToUString(guid);
1015+
UString text;
1016+
header = data.mid(itemOffset + entryOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_ENTRY));
1017+
body = data.mid(itemOffset + entryOffset + header.size(), parsed.entry_size() - header.size());
1018+
1019+
// Add info
1020+
UINT32 entrySize = (UINT32)header.size() + (UINT32)body.size();
1021+
info = UString("Region type: ") + guidToUString(guid, false) + "\n";
1022+
info += UString("Region id: ");
1023+
for (UINT8 i = 0; i < 16; i++) {
1024+
info += usprintf("%02X", *(const UINT8*)(entry->region_id().c_str() + i));
10371025
}
1026+
info += usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRegion address: %08Xh\nRegion size: %08Xh\nAttributes: %08Xh",
1027+
entrySize, entrySize,
1028+
(UINT32)header.size(), (UINT32)header.size(),
1029+
(UINT32)body.size(), (UINT32)body.size(),
1030+
(UINT32)entry->region_base(),
1031+
(UINT32)entry->region_size(),
1032+
entry->attributes());
10381033

1039-
// TODO: make sure that the only hash possible here is SHA256
1034+
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) {
1035+
if (!protectedRangeFound) {
1036+
securityInfo += usprintf("Insyde Flash Device Map found at base %08Xh\nProtected ranges:\n", model->base(headerIndex));
1037+
protectedRangeFound = true;
1038+
}
1039+
1040+
// TODO: make sure that the only hash possible here is SHA256
1041+
1042+
// Add this region to the list of Insyde protected regions
1043+
PROTECTED_RANGE range = {};
1044+
range.Offset = (UINT32)entry->region_base();
1045+
range.Size = (UINT32)entry->region_size();
1046+
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
1047+
range.Type = PROTECTED_RANGE_VENDOR_HASH_INSYDE;
1048+
range.Hash = body;
1049+
protectedRanges.push_back(range);
1050+
1051+
securityInfo += usprintf("Address: %08Xh Size: %Xh\nHash: ", range.Offset, range.Size) + UString(body.toHex().constData()) + "\n";
1052+
}
10401053

1041-
// Add this region to the list of Insyde protected regions
1042-
PROTECTED_RANGE range = {};
1043-
range.Offset = (UINT32)entry->region_base();
1044-
range.Size = (UINT32)entry->region_size();
1045-
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
1046-
range.Type = PROTECTED_RANGE_VENDOR_HASH_INSYDE;
1047-
range.Hash = body;
1048-
protectedRanges.push_back(range);
1054+
// Add tree item
1055+
model->addItem(entryOffset, Types::InsydeFlashDeviceMapEntry, 0, name, text, info, header, body, UByteArray(), Fixed, headerIndex);
10491056

1050-
securityInfo += usprintf("Address: %08Xh Size: %Xh\nHash: ", range.Offset, range.Size) + UString(body.toHex().constData()) + "\n";
1057+
entryOffset += entrySize;
10511058
}
1052-
1053-
// Add tree item
1054-
model->addItem(entryOffset, Types::InsydeFlashDeviceMapEntry, 0, name, text, info, header, body, UByteArray(), Fixed, headerIndex);
10551059

1056-
entryOffset += entrySize;
1060+
if (protectedRangeFound) {
1061+
securityInfo += "\n";
1062+
}
10571063
}
1058-
1059-
if (protectedRangeFound) {
1060-
securityInfo += "\n";
1064+
catch (...) {
1065+
// Parsing failed
10611066
}
10621067
}
10631068
else {

0 commit comments

Comments
 (0)