ShellPkg/SmbiosView: Improve SMBIOS Type 42 decoding

Update smbiosview to decode Management Controller Host Interface (Type 42) records more clearly and robustly.

The MC host interface type table only reported MCTP host interfaces as a generic range. Add the MCTP host interface subtype values defined in MdePkg, including PCIe VDM and MMBI, so Type 42 records can be identified from smbiosview output.

Also improve Type 42 formatted-area parsing by using unaligned reads for InterfaceTypeSpecificData, validating the formatted structure length before reading protocol records, and advancing each protocol record by its full header and data length.

This prevents protocol record mis-parsing when ProtocolTypeDataLen is zero, such as for IPMI-over-MMBI Type 42 records.

Change-Id: I10c974560ff2a5385d159494a5b285569003a061
Signed-off-by: Darren Dong <darren.dong@intel.com>
Signed-off-by: Liangqi Zhu <liangqi.zhu@intel.com>
This commit is contained in:
Darren Dong 2026-07-02 22:13:12 +08:00
parent 0809aa4dce
commit 7934dc56df
2 changed files with 83 additions and 9 deletions

View file

@ -1285,30 +1285,40 @@ SmbiosPrintStructure (
{
MC_HOST_INTERFACE_PROTOCOL_RECORD *MCHostInterfaceProtocolRecord;
UINT8 *RecordsPointer;
UINT8 *RecordsEnd;
UINT8 MCHostInterfaceProtocolNumber;
UINT8 ProtocolTypeDataLen;
UINT8 InterfaceTypeSpecificDataLength;
UINTN RecordLength;
DisplayMCHostInterfaceType (Struct->Type42->InterfaceType, Option);
if (AE_SMBIOS_VERSION (0x3, 0x2)) {
UINT32 DataValue = 0;
PRINT_STRUCT_VALUE_H (Struct, Type42, InterfaceTypeSpecificDataLength);
if (Struct->Type42->InterfaceTypeSpecificDataLength < 4) {
InterfaceTypeSpecificDataLength = Struct->Type42->InterfaceTypeSpecificDataLength;
if (InterfaceTypeSpecificDataLength < 4) {
ShellPrintDefaultEx (L"WARNING: InterfaceTypeSpecificDataLength should be >= 4.\n");
}
if (Struct->Hdr->Length < OFFSET_OF (SMBIOS_TABLE_TYPE42, InterfaceTypeSpecificData) + InterfaceTypeSpecificDataLength + 1) {
ShellPrintDefaultEx (L"WARNING: Type 42 structure length is too small for InterfaceTypeSpecificData and protocol count.\n");
break;
}
ShellPrintDefaultEx (L"InterfaceTypeSpecificData\n");
// Decode and interpret InterfaceTypeSpecificData based on the InterfaceType
switch (Struct->Type42->InterfaceType) {
case MCHostInterfaceTypeOemDefined:
// The first four bytes are the vendor ID (MSB first), as assigned by the Internet Assigned Numbers Authority (IANA) as "Enterprise Number".
// See https://www.iana.org/assignments/enterprise-numbers.txt
ShellPrintDefaultEx (L"Vendor ID (IANA Enterprise Number): %d", (UINT32)*(Struct->Type42->InterfaceTypeSpecificData));
DataValue = ReadUnaligned32 ((UINT32 *)(UINTN)Struct->Type42->InterfaceTypeSpecificData);
ShellPrintDefaultEx (L"Vendor ID (IANA Enterprise Number): %d\n", DataValue);
break;
// As defined in MCTP Host Interface Specification, DSP0256
case MCHostInterfaceTypeMMBI:
// For MCTP interface type of MMBI; this defines the pointer to the MMBI capability descriptor, as defined in DSP0282, Section 7.1
DataValue = *(UINT32 *)Struct->Type42->InterfaceTypeSpecificData;
DataValue = ReadUnaligned32 ((UINT32 *)(UINTN)Struct->Type42->InterfaceTypeSpecificData);
ShellPrintDefaultEx (L"Pointer to MMBI capability descriptor: 0x%x\n", DataValue);
break;
@ -1317,24 +1327,36 @@ SmbiosPrintStructure (
case MCHostInterfaceTypeKCS:
// switch case fall through
// For MCTP interface type of I2C, I3C, KCS; this value is reserved and must be 0
DataValue = *(UINT32 *)Struct->Type42->InterfaceTypeSpecificData;
DataValue = ReadUnaligned32 ((UINT32 *)(UINTN)Struct->Type42->InterfaceTypeSpecificData);
ShellPrintDefaultEx (L"For Interface type I2C, I3C or KCS, InterfaceTypeSpecificData is reserved and must be 0.\n");
ShellPrintDefaultEx (L"Actual value is : 0x%x\n", DataValue);
break;
default:
// The decoding is not defined for these values in SMBIOS 3.8.0. The value is dumped
PRINT_BIT_FIELD (Struct, Type42, InterfaceTypeSpecificData, Struct->Type42->InterfaceTypeSpecificDataLength);
PRINT_BIT_FIELD (Struct, Type42, InterfaceTypeSpecificData, InterfaceTypeSpecificDataLength);
break;
}
RecordsPointer = (UINT8 *)(&Struct->Type42->InterfaceTypeSpecificData[0] + Struct->Type42->InterfaceTypeSpecificDataLength);
RecordsPointer = (UINT8 *)(&Struct->Type42->InterfaceTypeSpecificData[0] + InterfaceTypeSpecificDataLength);
RecordsEnd = (UINT8 *)Struct->Raw + Struct->Hdr->Length;
MCHostInterfaceProtocolNumber = *RecordsPointer;
ShellPrintDefaultEx (L"MCHostInterfaceProtocol Number: %d\n", MCHostInterfaceProtocolNumber);
MCHostInterfaceProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD *)(RecordsPointer + 1);
for (Index = 0; Index < MCHostInterfaceProtocolNumber; Index++) {
if ((UINT8 *)MCHostInterfaceProtocolRecord + OFFSET_OF (MC_HOST_INTERFACE_PROTOCOL_RECORD, ProtocolTypeData) > RecordsEnd) {
ShellPrintDefaultEx (L"WARNING: Type 42 protocol record #%d header is outside the structure length.\n", Index);
break;
}
ProtocolTypeDataLen = MCHostInterfaceProtocolRecord->ProtocolTypeDataLen;
RecordLength = OFFSET_OF (MC_HOST_INTERFACE_PROTOCOL_RECORD, ProtocolTypeData) + ProtocolTypeDataLen;
if ((UINT8 *)MCHostInterfaceProtocolRecord + RecordLength > RecordsEnd) {
ShellPrintDefaultEx (L"WARNING: Type 42 protocol record #%d data is outside the structure length.\n", Index);
break;
}
ShellPrintDefaultEx (L"#%d MCHostInterfaceProtocolType: ", Index);
switch (MCHostInterfaceProtocolRecord->ProtocolType) {
case MCHostInterfaceProtocolTypeIPMI:
@ -1359,7 +1381,7 @@ SmbiosPrintStructure (
}
PRINT_SMBIOS_BIT_FIELD (Struct, MCHostInterfaceProtocolRecord->ProtocolTypeData, ProtocolTypeData, ProtocolTypeDataLen);
MCHostInterfaceProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD *)((UINT8 *)MCHostInterfaceProtocolRecord + ProtocolTypeDataLen);
MCHostInterfaceProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD *)((UINT8 *)MCHostInterfaceProtocolRecord + RecordLength);
}
}

View file

@ -3673,8 +3673,60 @@ TABLE_ITEM IPMIDIBMCInterfaceTypeTable[] = {
TABLE_ITEM MCHostInterfaceTypeTable[] = {
{
0x3F00,
L" MCTP Host Interface "
0x02,
L" KCS: Keyboard Controller Style "
},
{
0x03,
L" 8250 UART Register Compatible "
},
{
0x04,
L" 16450 UART Register Compatible "
},
{
0x05,
L" 16550/16550A UART Register Compatible "
},
{
0x06,
L" 16650/16650A UART Register Compatible "
},
{
0x07,
L" 16750/16750A UART Register Compatible "
},
{
0x08,
L" 16850/16850A UART Register Compatible "
},
{
0x09,
L" I2C/SMBus "
},
{
0x0A,
L" I3C "
},
{
0x0B,
L" PCIe VDM "
},
{
0x0C,
L" MMBI "
},
{
0x0D,
L" PCC "
},
{
0x0E,
L" UCIe "
},
{
0x0F,
L" USB "
},
{
0x40,