diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-01 01:21:50 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-01 01:21:50 -0400 |
| commit | 0055d732c38518bae3a0a58e8d4a6e427317ad8c (patch) | |
| tree | 33917dd20c82a3003053440305b5aa88204cef5f /kernel/gsp_phys_vbios.c | |
| parent | 60afa9a299889e247b0dee1570956b9fbedfbf77 (diff) | |
| download | open-iov-0055d732c38518bae3a0a58e8d4a6e427317ad8c.tar.gz open-iov-0055d732c38518bae3a0a58e8d4a6e427317ad8c.zip | |
gsp-phys: fix the WPR2-up release hand-back and tighten FWSEC/VBIOS checks
Diffstat (limited to 'kernel/gsp_phys_vbios.c')
| -rw-r--r-- | kernel/gsp_phys_vbios.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/kernel/gsp_phys_vbios.c b/kernel/gsp_phys_vbios.c index 4c35636..fa7849d 100644 --- a/kernel/gsp_phys_vbios.c +++ b/kernel/gsp_phys_vbios.c @@ -12,6 +12,7 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/io.h> +#include <linux/overflow.h> #include <linux/string.h> #include <linux/slab.h> #include <asm/unaligned.h> @@ -210,6 +211,12 @@ static int gsp_phys_vbios_find_pci_header(void __iomem *bar0, u32 *pci_offset) return -EINVAL; } + if (image_offset & 0x3) { + pr_err("gsp-phys-vbios: IFR image offset 0x%x is not 4-byte aligned\n", + image_offset); + return -EINVAL; + } + if (image_offset > GSP_PHYS_VBIOS_MAX_SIZE - sizeof(u32)) { pr_err("gsp-phys-vbios: IFR image offset 0x%x out of range\n", image_offset); @@ -400,7 +407,7 @@ int gsp_phys_vbios_read(struct gsp_phys_vbios *img, struct pci_dev *pdev, void __iomem *bar0) { u32 pci_offset = 0, bios_size = 0, expansion_rom_offset = 0; - u32 rom_sig; + u32 rom_sig, rom_end; int ret; if (!img || !bar0) @@ -438,9 +445,10 @@ int gsp_phys_vbios_read(struct gsp_phys_vbios *img, struct pci_dev *pdev, pr_err("gsp-phys-vbios: expansion ROM walk failed: %d\n", ret); return ret; } - if (bios_size > GSP_PHYS_VBIOS_MAX_SIZE) { - pr_err("gsp-phys-vbios: expansion ROM size 0x%x exceeds the window\n", - bios_size); + if (check_add_overflow(pci_offset, bios_size, &rom_end) || + rom_end > GSP_PHYS_VBIOS_MAX_SIZE) { + pr_err("gsp-phys-vbios: expansion ROM span 0x%x+0x%x exceeds the window\n", + pci_offset, bios_size); return -EINVAL; } @@ -677,9 +685,7 @@ int gsp_phys_vbios_parse_fwsec(const struct gsp_phys_vbios *img, &data_ptr)) continue; } else { - if (!gsp_phys_img_read(img, token_offset + 4, 2, - &data_ptr)) - continue; + data_ptr = 0; } if (token_id == GSP_PHYS_BIT_TOKEN_BIOSDATA && @@ -703,10 +709,12 @@ int gsp_phys_vbios_parse_fwsec(const struct gsp_phys_vbios *img, continue; { - u32 table_offset = img->expansion_rom_offset + - table_ptr; - u32 table_version, table_hdr_size, entry_size; - u32 entry_count, j; + u32 table_offset, table_version, table_hdr_size; + u32 entry_size, entry_count, j; + + if (check_add_overflow(img->expansion_rom_offset, + table_ptr, &table_offset)) + continue; if (!gsp_phys_img_read(img, table_offset, 1, &table_version) || |
