diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2019-12-21 08:09:56 +0100 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2020-01-12 13:16:04 -0500 |
commit | c08406033fe83a4cb307f2a2e949c59bb86b4f49 (patch) | |
tree | 5b86ff0a167ca4851fae874d21b11514010d9904 | |
parent | 040a3c33623ba4bd11588ab0820281b854a3ffaf (diff) | |
download | linux-c08406033fe83a4cb307f2a2e949c59bb86b4f49.tar.bz2 |
iscsi_ibft: Don't limits Targets and NICs to two
According to iSCSI Boot Firmware Table Version 1.03 [1], the length of
the control table is ">= 18", where the optional expansion structure
pointer follow the mandatory ones. This allows for more than two NICs
and Targets.
[1] ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_firmware_table_v1.03.pdf
Let's enforce the minimum length of the control structure instead
instead of limiting it to the smallest allowed size.
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Signed-off-by: Konrad Rzeszutek Wilk <konrad@darnok.org>
-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) { |