| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright 2007-2010 Red Hat, Inc. |
|---|
| 3 | 4 | * by Peter Jones <pjones@redhat.com> |
|---|
| .. | .. |
|---|
| 7 | 8 | * by Konrad Rzeszutek <ketuzsezr@darnok.org> |
|---|
| 8 | 9 | * |
|---|
| 9 | 10 | * This code exposes the iSCSI Boot Format Table to userland via sysfs. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 12 | | - * it under the terms of the GNU General Public License v2.0 as published by |
|---|
| 13 | | - * the Free Software Foundation |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 18 | | - * GNU General Public License for more details. |
|---|
| 19 | 11 | * |
|---|
| 20 | 12 | * Changelog: |
|---|
| 21 | 13 | * |
|---|
| .. | .. |
|---|
| 63 | 55 | * |
|---|
| 64 | 56 | * 27 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> |
|---|
| 65 | 57 | * First version exposing iBFT data via a binary /sysfs. (v0.1) |
|---|
| 66 | | - * |
|---|
| 67 | 58 | */ |
|---|
| 68 | 59 | |
|---|
| 69 | 60 | |
|---|
| .. | .. |
|---|
| 113 | 104 | u16 tgt0_off; |
|---|
| 114 | 105 | u16 nic1_off; |
|---|
| 115 | 106 | u16 tgt1_off; |
|---|
| 107 | + u16 expansion[]; |
|---|
| 116 | 108 | } __attribute__((__packed__)); |
|---|
| 117 | 109 | |
|---|
| 118 | 110 | struct ibft_initiator { |
|---|
| .. | .. |
|---|
| 244 | 236 | "found %d instead!\n", t, id, hdr->id); |
|---|
| 245 | 237 | return -ENODEV; |
|---|
| 246 | 238 | } |
|---|
| 247 | | - if (hdr->length != length) { |
|---|
| 239 | + if (length && hdr->length != length) { |
|---|
| 248 | 240 | printk(KERN_ERR "iBFT error: We expected the %s " \ |
|---|
| 249 | 241 | "field header.length to have %d but " \ |
|---|
| 250 | 242 | "found %d instead!\n", t, length, hdr->length); |
|---|
| .. | .. |
|---|
| 429 | 421 | |
|---|
| 430 | 422 | switch (type) { |
|---|
| 431 | 423 | case ISCSI_BOOT_ACPITBL_SIGNATURE: |
|---|
| 432 | | - str += sprintf_string(str, ACPI_NAME_SIZE, |
|---|
| 424 | + str += sprintf_string(str, ACPI_NAMESEG_SIZE, |
|---|
| 433 | 425 | entry->header->header.signature); |
|---|
| 434 | 426 | break; |
|---|
| 435 | 427 | case ISCSI_BOOT_ACPITBL_OEM_ID: |
|---|
| .. | .. |
|---|
| 758 | 750 | control = (void *)header + sizeof(*header); |
|---|
| 759 | 751 | end = (void *)control + control->hdr.length; |
|---|
| 760 | 752 | eot_offset = (void *)header + header->header.length - (void *)control; |
|---|
| 761 | | - rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, |
|---|
| 762 | | - sizeof(*control)); |
|---|
| 753 | + rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, 0); |
|---|
| 763 | 754 | |
|---|
| 764 | 755 | /* iBFT table safety checking */ |
|---|
| 765 | 756 | rc |= ((control->hdr.index) ? -ENODEV : 0); |
|---|
| 757 | + rc |= ((control->hdr.length < sizeof(*control)) ? -ENODEV : 0); |
|---|
| 766 | 758 | if (rc) { |
|---|
| 767 | 759 | printk(KERN_ERR "iBFT error: Control header is invalid!\n"); |
|---|
| 768 | 760 | return rc; |
|---|
| 769 | 761 | } |
|---|
| 770 | | - for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) { |
|---|
| 762 | + for (ptr = &control->initiator_off; ptr + sizeof(u16) <= end; ptr += sizeof(u16)) { |
|---|
| 771 | 763 | offset = *(u16 *)ptr; |
|---|
| 772 | 764 | if (offset && offset < header->header.length && |
|---|
| 773 | 765 | offset < eot_offset) { |
|---|