summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_vbios.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_vbios.c')
-rw-r--r--kernel/gsp_phys_vbios.c30
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) ||