smbios: Add length sanity checking

D28743 was commited, reverted and then f689cb23b2 landed before it
was recommitted. However, D28743 included an extra length check. Redo
that functionality so we check both the number of entries as well as the
length checks for wacky data.

Sponsored by:		Netflix
Reviewed by:		gallatin
Differential Revision:	https://reviews.freebsd.org/D45763
This commit is contained in:
Warner Losh 2024-07-24 23:02:27 -06:00
parent ce41bee0b4
commit 06326613af
2 changed files with 7 additions and 5 deletions

View file

@ -192,8 +192,8 @@ ipmi_smbios_probe(struct ipmi_get_info *info)
/* Now map the actual table and walk it looking for an IPMI entry. */
table = pmap_mapbios(header->structure_table_address,
header->structure_table_length);
smbios_walk_table(table, header->number_structures, smbios_ipmi_info,
info);
smbios_walk_table(table, header->number_structures,
header->structure_table_length, smbios_ipmi_info, info);
/* Unmap everything. */
pmap_unmapbios(table, header->structure_table_length);

View file

@ -80,11 +80,13 @@ struct smbios_structure_header {
typedef void (*smbios_callback_t)(struct smbios_structure_header *, void *);
static inline void
smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
smbios_walk_table(uint8_t *p, int entries, vm_size_t len,
smbios_callback_t cb, void *arg)
{
struct smbios_structure_header *s;
uint8_t *endp = p + len;
while (entries--) {
while (entries-- && p < endp) {
s = (struct smbios_structure_header *)p;
cb(s, arg);
@ -93,7 +95,7 @@ smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
* formatted area of this structure.
*/
p += s->length;
while (!(p[0] == 0 && p[1] == 0))
while (p + 1 < endp && !(p[0] == 0 && p[1] == 0))
p++;
/*