The branch main has been updated by olce: URL: https://cgit.FreeBSD.org/src/commit/?id=7e61fc76400cce08de39adde99b879f0bca21b7d
commit 7e61fc76400cce08de39adde99b879f0bca21b7d Author: Olivier Certner <o...@freebsd.org> AuthorDate: 2025-03-04 11:17:45 +0000 Commit: Olivier Certner <o...@freebsd.org> CommitDate: 2025-03-11 13:54:09 +0000 libsa: smbios: Stop parsing on an End-of-Table structure This structure exists since SMBIOS v2.2 and indicates that there are no structures to be parsed beyond this point. For backwards compatibility, the standard recommends that system software ensures that this structure covers the rest of the SMBIOS structure table area as reported by the Structure Table Address, and the Structure Table Maximum Size (64-bit entry point) or the Structure Table Length (32-bit entry point), which makes existing parsers continue to work correctly as they usually ignore unknown structure types. However, this is not a requirement, so be bullet proof and immediately stop parsing in this case. Reviewed by: imp, markj MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D49285 --- stand/libsa/smbios.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/stand/libsa/smbios.c b/stand/libsa/smbios.c index e726dfeb7af3..50cab3eee939 100644 --- a/stand/libsa/smbios.c +++ b/stand/libsa/smbios.c @@ -92,6 +92,7 @@ #define SMBIOS_SIG "_SM_" #define SMBIOS3_SIG "_SM3_" #define SMBIOS_DMI_SIG "_DMI_" +#define SMBIOS_EOT_TYPE 0x7f /* * 5.1 General @@ -504,6 +505,9 @@ smbios_parse_table(const caddr_t addr) (size & 0x7fff) : (size << 10); break; + case SMBIOS_EOT_TYPE: /* 3.3.42 End-of-Table (Type 127) */ + return (NULL); + default: /* skip other types */ break; } @@ -529,15 +533,19 @@ smbios_find_struct(int type) ep = smbios.addr + smbios.length; for (dmi = smbios.addr, i = 0; dmi < ep && i < smbios.count; i++) { - if (SMBIOS_GET8(dmi, 0) == type) { - return dmi; - } + const uint8_t seen_type = SMBIOS_GET8(dmi, 0); + + if (seen_type == type) + return (dmi); + if (seen_type == SMBIOS_EOT_TYPE) + /* End of table. */ + break; /* Find structure terminator. */ dmi = SMBIOS_GETSTR(dmi); - while (SMBIOS_GET16(dmi, 0) != 0 && dmi < ep) { + while (SMBIOS_GET16(dmi, 0) != 0 && dmi < ep) dmi++; - } - dmi += 2; /* For checksum */ + /* Skip it. */ + dmi += 2; } return (NULL); @@ -632,8 +640,8 @@ smbios_detect(const caddr_t addr) if (smbios.addr == NULL) return; - for (dmi = smbios.addr, i = 0; - dmi < smbios.addr + smbios.length && i < smbios.count; i++) + for (dmi = smbios.addr, i = 0; dmi != NULL && + dmi < smbios.addr + smbios.length && i < smbios.count; i++) dmi = smbios_parse_table(dmi); setenv("smbios.entry_point_type",