From: Guixin Liu <kanie@linux.alibaba.com>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org
Subject: [PATCH] PCI: Check rom image addr at every step
Date: Fri, 14 Nov 2025 14:34:11 +0800 [thread overview]
Message-ID: <20251114063411.88744-1-kanie@linux.alibaba.com> (raw)
We meet a crash when running stress-ng:
BUG: unable to handle page fault for address: ffa0000007f40000
RIP: 0010:pci_get_rom_size+0x52/0x220
Call Trace:
<TASK>
pci_map_rom+0x80/0x130
pci_read_rom+0x4b/0xe0
kernfs_file_read_iter+0x96/0x180
vfs_read+0x1b1/0x300
ksys_read+0x63/0xe0
do_syscall_64+0x34/0x80
entry_SYSCALL_64_after_hwframe+0x78/0xe2
Bcause of broken rom space, before calling readl(pds), pds already
points to the rom space end (rom + size - 1), invoking readl()
would therefore cause an out-of-bounds access and trigger a crash.
Fix this by adding every step address checking.
Fixes: 47b975d234ea ("PCI: Avoid iterating through memory outside the resource window")
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
drivers/pci/rom.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index e18d3a4383ba..f9377ad3f89f 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -69,6 +69,10 @@ void pci_disable_rom(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(pci_disable_rom);
+#define PCI_ROM_DATA_STRUCT_OFFSET 24
+#define PCI_ROM_LAST_IMAGE_OFFSET 21
+#define PCI_ROM_LAST_IMAGE_LEN_OFFSET 16
+
/**
* pci_get_rom_size - obtain the actual size of the ROM image
* @pdev: target PCI device
@@ -86,28 +90,41 @@ static size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom,
void __iomem *image;
int last_image;
unsigned int length;
+ void __iomem *end = rom + size;
image = rom;
do {
void __iomem *pds;
+
+ if (image + 2 >= end)
+ break;
+
/* Standard PCI ROMs start out with these bytes 55 AA */
if (readw(image) != 0xAA55) {
pci_info(pdev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
readw(image));
break;
}
+
+ if (image + PCI_ROM_DATA_STRUCT_OFFSET + 2 >= end)
+ break;
/* get the PCI data structure and check its "PCIR" signature */
- pds = image + readw(image + 24);
+ pds = image + readw(image + PCI_ROM_DATA_STRUCT_OFFSET);
+ if (pds + 4 >= end)
+ break;
if (readl(pds) != 0x52494350) {
pci_info(pdev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
readl(pds));
break;
}
- last_image = readb(pds + 21) & 0x80;
- length = readw(pds + 16);
+
+ if (pds + PCI_ROM_LAST_IMAGE_OFFSET + 1 >= end)
+ break;
+ last_image = readb(pds + PCI_ROM_LAST_IMAGE_OFFSET) & 0x80;
+ length = readw(pds + PCI_ROM_LAST_IMAGE_LEN_OFFSET);
image += length * 512;
/* Avoid iterating through memory outside the resource window */
- if (image >= rom + size)
+ if (image + 2 >= end)
break;
if (!last_image) {
if (readw(image) != 0xAA55) {
--
2.43.0
next reply other threads:[~2025-11-14 6:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-14 6:34 Guixin Liu [this message]
2025-11-18 2:48 ` [PATCH] PCI: Check rom image addr at every step Guixin Liu
2025-11-18 15:47 ` Andy Shevchenko
2025-11-19 7:10 ` Guixin Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251114063411.88744-1-kanie@linux.alibaba.com \
--to=kanie@linux.alibaba.com \
--cc=bhelgaas@google.com \
--cc=linux-pci@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.