On 20 March 2015 at 09:59, Jean Delvare <[email protected]> wrote: > dmi_num is a u16, dmi_len is a u32, so this construct: > > dmi_num = dmi_len / 4; > > would result in an integer overflow for a DMI table larger than > 256 kB. I've never see such a large table so far, but SMBIOS 3.0 > makes it possible so maybe we'll see such tables in the future. > > So instead of faking a structure count when the entry point does > not provide it, adjust the loop condition in dmi_table() to properly > deal with the case where dmi_num is not set. > > Signed-off-by: Jean Delvare <[email protected]> > Cc: Matt Fleming <[email protected]> > Cc: Ard Biesheuvel <[email protected]> > Cc: Ivan Khoronzhuk <[email protected]>
Acked-by: Ard Biesheuvel <[email protected]> > --- > drivers/firmware/dmi_scan.c | 22 +++++++--------------- > 1 file changed, 7 insertions(+), 15 deletions(-) > > --- linux-4.0-rc4.orig/drivers/firmware/dmi_scan.c 2015-03-19 > 14:19:56.384426825 +0100 > +++ linux-4.0-rc4/drivers/firmware/dmi_scan.c 2015-03-20 09:23:37.689542485 > +0100 > @@ -86,10 +86,13 @@ static void dmi_table(u8 *buf, u32 len, > int i = 0; > > /* > - * Stop when we see all the items the table claimed to have > - * OR we run off the end of the table (also happens) > + * Stop when we have seen all the items the table claimed to have > + * (SMBIOS < 3.0 only) OR we reach an end-of-table marker OR we run > + * off the end of the table (should never happen but sometimes does > + * on bogus implementations.) > */ > - while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { > + while ((!num || i < num) && > + (data - buf + sizeof(struct dmi_header)) <= len) { > const struct dmi_header *dm = (const struct dmi_header *)data; > > /* > @@ -529,21 +532,10 @@ static int __init dmi_smbios3_present(co > if (memcmp(buf, "_SM3_", 5) == 0 && > buf[6] < 32 && dmi_checksum(buf, buf[6])) { > dmi_ver = get_unaligned_be16(buf + 7); > + dmi_num = 0; /* No longer specified */ > dmi_len = get_unaligned_le32(buf + 12); > dmi_base = get_unaligned_le64(buf + 16); > > - /* > - * The 64-bit SMBIOS 3.0 entry point no longer has a field > - * containing the number of structures present in the table. > - * Instead, it defines the table size as a maximum size, and > - * relies on the end-of-table structure type (#127) to be used > - * to signal the end of the table. > - * So let's define dmi_num as an upper bound as well: each > - * structure has a 4 byte header, so dmi_len / 4 is an upper > - * bound for the number of structures in the table. > - */ > - dmi_num = dmi_len / 4; > - > if (dmi_walk_early(dmi_decode) == 0) { > pr_info("SMBIOS %d.%d present.\n", > dmi_ver >> 8, dmi_ver & 0xFF); > > > -- > Jean Delvare > SUSE L3 Support -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/

