diff --git a/sys/dev/ipmi/ipmi_smbios.c b/sys/dev/ipmi/ipmi_smbios.c --- a/sys/dev/ipmi/ipmi_smbios.c +++ b/sys/dev/ipmi/ipmi_smbios.c @@ -192,8 +192,8 @@ /* 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); diff --git a/sys/dev/smbios/smbios.h b/sys/dev/smbios/smbios.h --- a/sys/dev/smbios/smbios.h +++ b/sys/dev/smbios/smbios.h @@ -80,11 +80,13 @@ 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 @@ * 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++; /*