On Wed, Jan 13, 2021 at 09:52:59AM +0100, Jean Delvare wrote: > If OEM type entries come before the type 1 entry (System > Information), we aren't able to decode them because we don't know > the vendor yet. To fix this, figure out the vendor during a first > pass, and walk the table again once we have the information. > > Signed-off-by: Jean Delvare <jdelv...@suse.de> > Reported-by: Erwan Velu <e.v...@criteo.com>
Tested. Addresses the issue I see with the HPE OEM 236 record. Thanks > --- > dmidecode.c | 50 +++++++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 45 insertions(+), 5 deletions(-) > > --- dmidecode.orig/dmidecode.c 2021-01-05 12:45:19.744939071 +0100 > +++ dmidecode/dmidecode.c 2021-01-05 12:50:22.518420537 +0100 > @@ -5182,6 +5182,51 @@ static void dmi_table_decode(u8 *buf, u3 > u8 *data; > int i = 0; > > + /* First pass: Save the vendor so that so that we can decode OEM types > */ > + data = buf; > + while ((i < num || !num) > + && data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure > header */ > + { > + u8 *next; > + struct dmi_header h; > + > + to_dmi_header(&h, data); > + > + /* > + * If a short entry is found (less than 4 bytes), not only it > + * is invalid, but we cannot reliably locate the next entry. > + * Also stop at end-of-table marker if so instructed. > + */ > + if (h.length < 4 || > + (h.type == 127 && > + (opt.flags & (FLAG_QUIET | FLAG_STOP_AT_EOT)))) > + break; > + i++; > + > + /* Look for the next handle */ > + next = data + h.length; > + while ((unsigned long)(next - buf + 1) < len > + && (next[0] != 0 || next[1] != 0)) > + next++; > + next += 2; > + > + /* Make sure the whole structure fits in the table */ > + if ((unsigned long)(next - buf) > len) > + break; > + > + /* Assign vendor for vendor-specific decodes later */ > + if (h.type == 1 && h.length >= 6) > + { > + dmi_set_vendor(_dmi_string(&h, data[0x04], 0), > + _dmi_string(&h, data[0x05], 0)); > + break; > + } > + > + data = next; > + } > + > + /* Second pass: Actually decode the data */ > + i = 0; > data = buf; > while ((i < num || !num) > && data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure > header */ > @@ -5241,11 +5286,6 @@ static void dmi_table_decode(u8 *buf, u3 > break; > } > > - /* assign vendor for vendor-specific decodes later */ > - if (h.type == 1 && h.length >= 6) > - dmi_set_vendor(_dmi_string(&h, data[0x04], 0), > - _dmi_string(&h, data[0x05], 0)); > - > /* Fixup a common mistake */ > if (h.type == 34) > dmi_fixup_type_34(&h, display); > > > -- > Jean Delvare > SUSE L3 Support -- ----------------------------------------------------------------------------- Jerry Hoemann Software Engineer Hewlett Packard Enterprise ----------------------------------------------------------------------------- _______________________________________________ https://lists.nongnu.org/mailman/listinfo/dmidecode-devel