All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net v3] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
@ 2026-07-22  3:16 Pu Lehui
  2026-07-22  3:37 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Pu Lehui @ 2026-07-22  3:16 UTC (permalink / raw)
  To: Andrew Lunn, Tony Nguyen, Przemek Kitszel, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jeff Garzik, Auke Kok,
	Breno Leitao
  Cc: bpf, linux-kernel, Pu Lehui, Pu Lehui

From: Pu Lehui <pulehui@huawei.com>

Syzkaller reported a kernel panic caused by an out-of-bounds MMIO
access in the e1000e driver.

[   82.868719][  T404] e1000e 0000:00:02.0: The NVM Checksum Is Not Valid
[   82.872328][  T404] Unable to handle kernel paging request at virtual address ffff80008894e090
[   83.085218][  T404] CPU: 2 UID: 0 PID: 404 Comm: bash Not tainted 7.2.0-rc2-g3f1f75536668 #1 PREEMPTLAZY
[   83.129013][  T404] pc : e1000_get_cfg_done_82571+0x70/0x158
[   83.140092][  T404] lr : e1000_get_cfg_done_82571+0x68/0x158
[   83.151196][  T404] sp : ffff80008ac37410
[   83.158922][  T404] x29: ffff80008ac37410 x28: ffff0000cd6a11b8 x27: ffff0000c58190d0
[   83.173919][  T404] x26: ffff0000cd6a11b8 x25: ffff0000cd6a0bc0 x24: ffff0000cd6a0000
[   83.189417][  T404] x23: 0000000000001010 x22: ffff0000cd6a11c0 x21: ffff0000cd6a11b8
[   83.205195][  T404] x20: 0000000000000064 x19: ffff80008894e090 x18: 0000000000000000
[   83.220545][  T404] x17: ffff800081c1a3f4 x16: ffff800081c19c10 x15: ffff800081e86510
[   83.235764][  T404] x14: 0000000000000001 x13: 0000000000000001 x12: ffff60001bc8a8b3
[   83.251301][  T404] x11: 1fffe0001bc8a8b2 x10: ffff60001bc8a8b2 x9 : ffff800081eae25c
[   83.266705][  T404] x8 : 00009fffe437574e x7 : ffff0000de454593 x6 : 0000000000000001
[   83.281919][  T404] x5 : ffff0000cf2b9640 x4 : 0000000000000000 x3 : dfff800000000000
[   83.297317][  T404] x2 : 0000000000000007 x1 : ffff0000cd6a11c0 x0 : 0000000000000000
[   83.312601][  T404] Call trace:
[   83.318662][  T404]  e1000_get_cfg_done_82571+0x70/0x158 (P)
[   83.329748][  T404]  e1000e_phy_hw_reset_generic+0x17c/0x1a8
[   83.341541][  T404]  e1000_probe+0xbd8/0x1988
[   83.350334][  T404]  local_pci_probe+0x84/0x130

Repetition steps:
1. Find PCI device which BAR0 size <= 4K. If it's:
   Device Addr: 0000:00:02.0   BAR0 SIZE: 4K
   Vendor/Device ID: 0x1af4 0x1004
2. Unbind the above PCI device
   echo '0000:00:02.0' > /sys/bus/pci/devices/0000:00:02.0/driver/unbind
3. Set the above device to e1000e new_id
   echo '1af4 1004' > /sys/bus/pci/drivers/e1000e/new_id

During e1000_probe(), the driver maps the device's BAR0 memory region.
If the device has a 4K BAR0, ioremap() maps only 4K of space. Later in
the probe process, when the NVM checksum validation fails, the driver
attempts to perform a hardware reset and falls back to the err_eeprom
cleanup path.

This cleanup path will trigger an OOB access kernel panic:
e1000_phy_hw_reset
  e1000e_phy_hw_reset_generic
    e1000_get_cfg_done_82571
      er32(EEMNGCTL)
        readl(hw->hw_addr + EEMNGCTL); <-- EEMNGCTL(0x1010) > 4K, OOB access

Fix this by verifying that the MMIO length (pci_resource_len(pdev, 0))
is large enough to encompass the highest register offset
(E1000_SYSSTMPH) accessed by the driver before calling ioremap(). This
ensures that subsequent register reads/writes remain strictly within the
mapped boundary.

Fixes: bc7f75fa9788 ("[E1000E]: New pci-express e1000 driver (currently for ICH9 devices only)")
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
v3:
- Align the minimum BAR0 size to the largest register access offset. (Andrew)

v2:
- Update comment about E1000_MMIO_LEN_MIN. (Breno)

 drivers/net/ethernet/intel/e1000e/netdev.c | 5 +++++
 drivers/net/ethernet/intel/e1000e/regs.h   | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 844f31ab37ad..46e58e926f7b 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -7450,6 +7450,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	mmio_len = pci_resource_len(pdev, 0);
 
 	err = -EIO;
+	if (mmio_len < E1000_MMIO_LEN_MIN) {
+		dev_err(&pdev->dev, "MMIO len is too small\n");
+		goto err_ioremap;
+	}
+
 	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
 	if (!adapter->hw.hw_addr)
 		goto err_ioremap;
diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h
index 6c0cd8cab3ef..1e875227eef2 100644
--- a/drivers/net/ethernet/intel/e1000e/regs.h
+++ b/drivers/net/ethernet/intel/e1000e/regs.h
@@ -242,4 +242,7 @@
 /* PHY registers */
 #define I82579_DFT_CTRL	PHY_REG(769, 20)
 
+/* Smallest BAR0 that covers every register the driver accesses */
+#define E1000_MMIO_LEN_MIN	(E1000_SYSSTMPH + sizeof(u32))
+
 #endif
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH net v3] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
  2026-07-22  3:16 [PATCH net v3] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size Pu Lehui
@ 2026-07-22  3:37 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-07-22  3:37 UTC (permalink / raw)
  To: Pu Lehui; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The newly introduced minimum BAR0 length check `E1000_MMIO_LEN_MIN` is too small because it fails to account for flash registers mapped into the GbE memory space for newer MACs, leaving the driver vulnerable to the same OOB MMIO access panics it attempts to fix.
--

--- Patch [1]: [PATCH net v3] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size ---
commit 9c24a014d2bfbd3a6822ff92be6a5c7aceb588d4
Author: Pu Lehui <pulehui@huawei.com>
Subject: e1000e: Fix out-of-bounds MMIO access by validating BAR0 size

This patch adds a check during e1000_probe() to validate that the device's
BAR0 size is large enough to cover the highest register offset (E1000_SYSSTMPH)
accessed by the driver. This is intended to fix a kernel panic caused by
out-of-bounds MMIO reads when dealing with small BAR0 allocations.

> diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h
> index 6c0cd8cab3ef2..1e875227eef24 100644
> --- a/drivers/net/ethernet/intel/e1000e/regs.h
> +++ b/drivers/net/ethernet/intel/e1000e/regs.h
[ ... ]
> @@ -242,4 +242,7 @@
>  /* PHY registers */
>  #define I82579_DFT_CTRL	PHY_REG(769, 20)
>  
> +/* Smallest BAR0 that covers every register the driver accesses */
> +#define E1000_MMIO_LEN_MIN	(E1000_SYSSTMPH + sizeof(u32))

[Severity: High]
This isn't a bug introduced by this patch, but does this minimum length
cover all register accesses for newer MACs?

For MAC types e1000_pch_spt and newer, the driver accesses flash registers
mapped at E1000_FLASH_BASE_ADDR (0xE000). For example, during flash read:

drivers/net/ethernet/intel/e1000e/ich8lan.c:e1000_init_nvm_params_ich8lan() {
    ...
    hw->flash_address = hw->hw_addr + E1000_FLASH_BASE_ADDR;
    ...
}

And then later accesses like:

drivers/net/ethernet/intel/e1000e/ich8lan.c:e1000_read_flash_data32_ich8lan() {
    ...
    *data = er32flash(ICH_FLASH_FDATA0);
    ...
}

This results in an access at offset 0xE010 (57360 bytes).

Since E1000_MMIO_LEN_MIN is currently based on E1000_SYSSTMPH
(0xB64C + 4 = 46672 bytes), could a malicious or mocked PCI device expose a
BAR0 size of 12 pages (49152 bytes), pass this new check, and still trigger
an out-of-bounds MMIO read panic when accessing the flash space?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260722031603.1471127-1-pulehui@huaweicloud.com?part=1

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-22  3:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-22  3:16 [PATCH net v3] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size Pu Lehui
2026-07-22  3:37 ` sashiko-bot

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.