diff options
-rw-r--r-- | drivers/firmware/iscsi_ibft.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 7e12cbdf957c..96758b71a8db 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -104,6 +104,7 @@ struct ibft_control { u16 tgt0_off; u16 nic1_off; u16 tgt1_off; + u16 expansion[0]; } __attribute__((__packed__)); struct ibft_initiator { @@ -235,7 +236,7 @@ static int ibft_verify_hdr(char *t, struct ibft_hdr *hdr, int id, int length) "found %d instead!\n", t, id, hdr->id); return -ENODEV; } - if (hdr->length != length) { + if (length && hdr->length != length) { printk(KERN_ERR "iBFT error: We expected the %s " \ "field header.length to have %d but " \ "found %d instead!\n", t, length, hdr->length); @@ -749,16 +750,16 @@ static int __init ibft_register_kobjects(struct acpi_table_ibft *header) control = (void *)header + sizeof(*header); end = (void *)control + control->hdr.length; eot_offset = (void *)header + header->header.length - (void *)control; - rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, - sizeof(*control)); + rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, 0); /* iBFT table safety checking */ rc |= ((control->hdr.index) ? -ENODEV : 0); + rc |= ((control->hdr.length < sizeof(*control)) ? -ENODEV : 0); if (rc) { printk(KERN_ERR "iBFT error: Control header is invalid!\n"); return rc; } - for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) { + for (ptr = &control->initiator_off; ptr + sizeof(u16) <= end; ptr += sizeof(u16)) { offset = *(u16 *)ptr; if (offset && offset < header->header.length && offset < eot_offset) { |