@@ -630,6 +630,8 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
630
630
result = parsePdrRegion (region.data , region.offset , index, regionIndex);
631
631
break ;
632
632
case Subtypes::DevExp1Region:
633
+ result = parseDevExp1Region (region.data , region.offset , index, regionIndex);
634
+ break ;
633
635
case Subtypes::Bios2Region:
634
636
case Subtypes::MicrocodeRegion:
635
637
case Subtypes::EcRegion:
@@ -779,6 +781,33 @@ USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffs
779
781
return U_SUCCESS;
780
782
}
781
783
784
+ USTATUS FfsParser::parseDevExp1Region (const UByteArray & devExp1, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
785
+ {
786
+ // Check sanity
787
+ if (devExp1.isEmpty ())
788
+ return U_EMPTY_REGION;
789
+
790
+ // Get info
791
+ UString name (" DevExp1 region" );
792
+ UString info = usprintf (" Full size: %Xh (%u)" , devExp1.size (), devExp1.size ());
793
+
794
+ bool emptyRegion = false ;
795
+ // Check for empty region
796
+ if (devExp1.size () == devExp1.count (' \xFF ' ) || devExp1.size () == devExp1.count (' \x00 ' )) {
797
+ // Further parsing not needed
798
+ emptyRegion = true ;
799
+ info += (" \n State: empty" );
800
+ }
801
+
802
+ // Add tree item
803
+ index = model->addItem (localOffset, Types::Region, Subtypes::DevExp1Region, name, UString (), info, UByteArray (), devExp1, UByteArray (), Fixed, parent);
804
+
805
+ if (!emptyRegion) {
806
+ meParser->parseMeRegionBody (index);
807
+ }
808
+ return U_SUCCESS;
809
+ }
810
+
782
811
USTATUS FfsParser::parseGenericRegion (const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
783
812
{
784
813
// Check sanity
@@ -1189,6 +1218,75 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
1189
1218
return U_SUCCESS;
1190
1219
}
1191
1220
1221
+ BOOLEAN FfsParser::microcodeHeaderValid (const INTEL_MICROCODE_HEADER* ucodeHeader)
1222
+ {
1223
+ // Check main reserved bytes to be zero
1224
+ bool reservedBytesValid = true ;
1225
+ for (UINT32 i = 0 ; i < sizeof (ucodeHeader->Reserved ); i++) {
1226
+ if (ucodeHeader->Reserved [i] != 0x00 ) {
1227
+ reservedBytesValid = false ;
1228
+ break ;
1229
+ }
1230
+ }
1231
+ if (!reservedBytesValid) {
1232
+ return FALSE ;
1233
+ }
1234
+
1235
+ // Check CpuFlags reserved bytes to be zero
1236
+ for (UINT32 i = 0 ; i < sizeof (ucodeHeader->CpuFlagsReserved ); i++) {
1237
+ if (ucodeHeader->CpuFlagsReserved [i] != 0x00 ) {
1238
+ reservedBytesValid = false ;
1239
+ break ;
1240
+ }
1241
+ }
1242
+ if (!reservedBytesValid) {
1243
+ return FALSE ;
1244
+ }
1245
+
1246
+ // Check data size to be multiple of 4
1247
+ if (ucodeHeader->DataSize % 4 != 0 ) {
1248
+ return FALSE ;
1249
+ }
1250
+
1251
+ // Check TotalSize to be greater then DataSize and multiple of 1024
1252
+ if (ucodeHeader->TotalSize <= ucodeHeader->DataSize || ucodeHeader->TotalSize % 1024 != 0 ) {
1253
+ return FALSE ;
1254
+ }
1255
+
1256
+ // Check date to be sane
1257
+ // Check day to be in 0x01-0x09, 0x10-0x19, 0x20-0x29, 0x30-0x31
1258
+ if (ucodeHeader->DateDay < 0x01 ||
1259
+ (ucodeHeader->DateDay > 0x09 && ucodeHeader->DateDay < 0x10 ) ||
1260
+ (ucodeHeader->DateDay > 0x19 && ucodeHeader->DateDay < 0x20 ) ||
1261
+ (ucodeHeader->DateDay > 0x29 && ucodeHeader->DateDay < 0x30 ) ||
1262
+ ucodeHeader->DateDay > 0x31 ) {
1263
+ return FALSE ;
1264
+ }
1265
+ // Check month to be in 0x01-0x09, 0x10-0x12
1266
+ if (ucodeHeader->DateMonth < 0x01 ||
1267
+ (ucodeHeader->DateMonth > 0x09 && ucodeHeader->DateMonth < 0x10 ) ||
1268
+ ucodeHeader->DateMonth > 0x12 ) {
1269
+ return FALSE ;
1270
+ }
1271
+ // Check year to be in 0x1990-0x1999, 0x2000-0x2009, 0x2010-0x2019, 0x2020-0x2029, 0x2030-0x2030, 0x2040-0x2049
1272
+ if (ucodeHeader->DateYear < 0x1990 ||
1273
+ (ucodeHeader->DateYear > 0x1999 && ucodeHeader->DateYear < 0x2000 ) ||
1274
+ (ucodeHeader->DateYear > 0x2009 && ucodeHeader->DateYear < 0x2010 ) ||
1275
+ (ucodeHeader->DateYear > 0x2019 && ucodeHeader->DateYear < 0x2020 ) ||
1276
+ (ucodeHeader->DateYear > 0x2029 && ucodeHeader->DateYear < 0x2030 ) ||
1277
+ (ucodeHeader->DateYear > 0x2039 && ucodeHeader->DateYear < 0x2040 ) ||
1278
+ ucodeHeader->DateYear > 0x2049 ) {
1279
+ return FALSE ;
1280
+ }
1281
+
1282
+ // Check loader revision to be sane
1283
+ if (ucodeHeader->LoaderRevision > INTEL_MICROCODE_MAX_LOADER_REVISION) {
1284
+ return FALSE ;
1285
+ }
1286
+
1287
+ return TRUE ;
1288
+ }
1289
+
1192
1290
USTATUS FfsParser::findNextRawAreaItem (const UModelIndex & index, const UINT32 localOffset, UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize)
1193
1291
{
1194
1292
UByteArray data = model->body (index);
@@ -1203,29 +1301,14 @@ USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 l
1203
1301
const UINT32 restSize = dataSize - offset;
1204
1302
if (readUnaligned (currentPos) == INTEL_MICROCODE_HEADER_VERSION_1) {// Intel microcode
1205
1303
// Check data size
1206
- if (restSize < sizeof (INTEL_MICROCODE_HEADER))
1207
- continue ;
1208
-
1209
- // Check microcode size
1210
- const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos;
1211
-
1212
- // Check reserved bytes
1213
- bool reservedBytesValid = true ;
1214
- for (UINT32 i = 0 ; i < sizeof (ucodeHeader->Reserved ); i++)
1215
- if (ucodeHeader->Reserved [i] != 0x00 ) {
1216
- reservedBytesValid = false ;
1217
- break ;
1218
- }
1219
- if (!reservedBytesValid)
1220
- continue ;
1221
-
1222
- // Data size is multiple of 4
1223
- if (ucodeHeader->DataSize % 4 != 0 ) {
1304
+ if (restSize < sizeof (INTEL_MICROCODE_HEADER)) {
1224
1305
continue ;
1225
1306
}
1226
1307
1227
- // TotalSize is greater then DataSize and is multiple of 1024
1228
- if (ucodeHeader->TotalSize <= ucodeHeader->DataSize || ucodeHeader->TotalSize % 1024 != 0 ) {
1308
+ // Check microcode header candidate
1309
+ const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos;
1310
+
1311
+ if (FALSE == microcodeHeaderValid (ucodeHeader)) {
1229
1312
continue ;
1230
1313
}
1231
1314
@@ -3742,47 +3825,27 @@ void FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & found,
3742
3825
USTATUS FfsParser::parseFitEntryMicrocode (const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
3743
3826
{
3744
3827
U_UNUSED_PARAMETER (parent);
3745
- if ((UINT32)microcode.size () < localOffset + sizeof (INTEL_MICROCODE_HEADER)) {
3828
+ if ((UINT32)microcode.size () - localOffset < sizeof (INTEL_MICROCODE_HEADER)) {
3746
3829
return U_INVALID_MICROCODE;
3747
3830
}
3748
3831
3749
- const INTEL_MICROCODE_HEADER* header = (const INTEL_MICROCODE_HEADER*)(microcode.constData () + localOffset);
3750
- if (header->Version != INTEL_MICROCODE_HEADER_VERSION_1) {
3751
- return U_INVALID_MICROCODE;
3752
- }
3753
-
3754
- bool reservedBytesValid = true ;
3755
- for (UINT8 i = 0 ; i < sizeof (header->Reserved ); i++)
3756
- if (header->Reserved [i] != 0x00 ) {
3757
- reservedBytesValid = false ;
3758
- break ;
3759
- }
3760
- if (!reservedBytesValid) {
3761
- return U_INVALID_MICROCODE;
3762
- }
3763
-
3764
- if (header->DataSize % 4 != 0 ) {
3832
+ const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)(microcode.constData () + localOffset);
3833
+ if (!microcodeHeaderValid (ucodeHeader)) {
3765
3834
return U_INVALID_MICROCODE;
3766
3835
}
3767
3836
3768
- if (header-> TotalSize <= header-> DataSize || header-> TotalSize % 1024 != 0 ) {
3837
+ if ((UINT32)microcode. size () - localOffset < ucodeHeader-> TotalSize ) {
3769
3838
return U_INVALID_MICROCODE;
3770
3839
}
3771
3840
3772
- UINT32 mcSize = header->TotalSize ;
3773
- if ((UINT32)microcode.size () < localOffset + mcSize) {
3774
- return U_INVALID_MICROCODE;
3775
- }
3776
-
3777
3841
// Valid microcode found
3778
3842
info = usprintf (" CpuSignature: %08Xh, Revision: %08Xh, Date: %02X.%02X.%04X" ,
3779
- header->CpuSignature ,
3780
- header->Revision ,
3781
- header->DateDay ,
3782
- header->DateMonth ,
3783
- header->DateYear
3784
- );
3785
- realSize = mcSize;
3843
+ ucodeHeader->CpuSignature ,
3844
+ ucodeHeader->Revision ,
3845
+ ucodeHeader->DateDay ,
3846
+ ucodeHeader->DateMonth ,
3847
+ ucodeHeader->DateYear );
3848
+ realSize = ucodeHeader->TotalSize ;
3786
3849
return U_SUCCESS;
3787
3850
}
3788
3851
@@ -4214,38 +4277,15 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
4214
4277
4215
4278
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)microcode.constData ();
4216
4279
4217
- // Header version is 1
4218
- if (ucodeHeader->Version != INTEL_MICROCODE_HEADER_VERSION_1) {
4219
- return U_INVALID_MICROCODE;
4220
- }
4221
-
4222
- // Reserved bytes are all zeroes
4223
- bool reservedBytesValid = true ;
4224
- for (UINT8 i = 0 ; i < sizeof (ucodeHeader->Reserved ); i++) {
4225
- if (ucodeHeader->Reserved [i] != 0x00 ) {
4226
- reservedBytesValid = false ;
4227
- break ;
4228
- }
4229
- }
4230
- if (!reservedBytesValid) {
4280
+ if (!microcodeHeaderValid (ucodeHeader)) {
4231
4281
return U_INVALID_MICROCODE;
4232
4282
}
4233
4283
4234
- // Data size is multiple of 4
4235
- if (ucodeHeader->DataSize % 4 != 0 ) {
4236
- return U_INVALID_MICROCODE;
4237
- }
4238
-
4239
- // TotalSize is greater then DataSize and is multiple of 1024
4240
- if (ucodeHeader->TotalSize <= ucodeHeader->DataSize || ucodeHeader->TotalSize % 1024 != 0 ) {
4241
- return U_INVALID_MICROCODE;
4242
- }
4243
-
4244
4284
// We have enough data to fit the whole TotalSize
4245
4285
if ((UINT32)microcode.size () < ucodeHeader->TotalSize ) {
4246
4286
return U_INVALID_MICROCODE;
4247
4287
}
4248
-
4288
+
4249
4289
// Valid microcode found
4250
4290
UINT32 dataSize = ucodeHeader->DataSize ;
4251
4291
if (dataSize == 0 )
@@ -4301,8 +4341,7 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
4301
4341
tempUcodeHeader->CpuSignature = entry->CpuSignature ;
4302
4342
UINT32 entryCalculated = calculateChecksum32 ((const UINT32*)tempMicrocode.constData (), sizeof (INTEL_MICROCODE_HEADER) + dataSize);
4303
4343
4304
-
4305
- extendedHeaderInfo += usprintf (" \n CPU signature #%u: %08Xh\n CPU flags #%u: %08Xh\n Checksum #%u: %08Xh, " ,
4344
+ extendedHeaderInfo += usprintf (" \n CPU signature #%u: %08Xh\n CPU flags #%u: %02Xh\n Checksum #%u: %08Xh, " ,
4306
4345
i + 1 , entry->CpuSignature ,
4307
4346
i + 1 , entry->CpuFlags ,
4308
4347
i + 1 , entry->Checksum )
@@ -4314,7 +4353,7 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
4314
4353
// Add info
4315
4354
UString name (" Intel microcode" );
4316
4355
UString info = usprintf (" Full size: %Xh (%u)\n Header size: %Xh (%u)\n Body size: %Xh (%u)\n Tail size: %Xh (%u)\n "
4317
- " Date: %02X.%02X.%04x\n CPU signature: %08Xh\n Revision: %08Xh\n Loader revision: %08Xh\n CPU flags: %08Xh \n Checksum: %08Xh, " ,
4356
+ " Date: %02X.%02X.%04x\n CPU signature: %08Xh\n Revision: %08Xh\n Loader revision: %08Xh\n CPU flags: %02Xh \n Checksum: %08Xh, " ,
4318
4357
dataSize, dataSize,
4319
4358
header.size (), header.size (),
4320
4359
body.size (), body.size (),
0 commit comments