diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c index 2a13fa6888ba..2acfe83928b6 100644 --- a/drivers/thunderbolt/eeprom.c +++ b/drivers/thunderbolt/eeprom.c @@ -324,7 +324,7 @@ int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid) } static int tb_drom_parse_entry_generic(struct tb_switch *sw, - struct tb_drom_entry_header *header) + const struct tb_drom_entry_header *header) { const struct tb_drom_entry_generic *entry = (const struct tb_drom_entry_generic *)header; @@ -360,7 +360,7 @@ static int tb_drom_parse_entry_generic(struct tb_switch *sw, } static int tb_drom_parse_entry_port(struct tb_switch *sw, - struct tb_drom_entry_header *header) + const struct tb_drom_entry_header *header) { struct tb_port *port; int res; @@ -386,11 +386,13 @@ static int tb_drom_parse_entry_port(struct tb_switch *sw, type &= 0xffffff; if (type == TB_TYPE_PORT) { - struct tb_drom_entry_port *entry = (void *) header; + const struct tb_drom_entry_port *entry = + (const struct tb_drom_entry_port *)header; + if (header->len != sizeof(*entry)) { tb_sw_warn(sw, "port entry has size %#x (expected %#zx)\n", - header->len, sizeof(struct tb_drom_entry_port)); + header->len, sizeof(*entry)); return -EIO; } port->link_nr = entry->link_nr; @@ -421,9 +423,16 @@ static int tb_drom_parse_entries(struct tb_switch *sw, size_t header_size) int res; while (pos < drom_size) { - struct tb_drom_entry_header *entry = (void *) (sw->drom + pos); - if (pos + 1 == drom_size || pos + entry->len > drom_size - || !entry->len) { + const struct tb_drom_entry_header *entry; + + if (drom_size - pos < sizeof(*entry)) { + tb_sw_warn(sw, "DROM buffer overrun\n"); + return -EIO; + } + + entry = (const struct tb_drom_entry_header *)(sw->drom + pos); + if (entry->len < sizeof(*entry) || + entry->len > drom_size - pos) { tb_sw_warn(sw, "DROM buffer overrun\n"); return -EIO; }