* [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
@ 2026-07-15 3:58 Pu Lehui
2026-07-20 1:25 ` Pu Lehui
2026-07-20 9:47 ` Breno Leitao
0 siblings, 2 replies; 7+ messages in thread
From: Pu Lehui @ 2026-07-15 3:58 UTC (permalink / raw)
To: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel
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 ensuring the MMIO length (pci_resource_len(pdev, 0)) is at
least 64K (0x10000) before proceeding with ioremap(). The 64K minimum
safely covers the maximum register offset accessed by the e1000e driver.
Fixes: bc7f75fa9788 ("[E1000E]: New pci-express e1000 driver (currently for ICH9 devices only)")
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
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..b63adeea1563 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)
+/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
+#define E1000_MMIO_LEN_MIN 0x10000
+
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
2026-07-15 3:58 [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size Pu Lehui
@ 2026-07-20 1:25 ` Pu Lehui
2026-07-20 9:47 ` Breno Leitao
1 sibling, 0 replies; 7+ messages in thread
From: Pu Lehui @ 2026-07-20 1:25 UTC (permalink / raw)
To: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel
Gentle ping~
Hi all, Is this commit looks proper?
On 2026/7/15 11:58, Pu Lehui wrote:
> 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 ensuring the MMIO length (pci_resource_len(pdev, 0)) is at
> least 64K (0x10000) before proceeding with ioremap(). The 64K minimum
> safely covers the maximum register offset accessed by the e1000e driver.
>
> Fixes: bc7f75fa9788 ("[E1000E]: New pci-express e1000 driver (currently for ICH9 devices only)")
> Signed-off-by: Pu Lehui <pulehui@huawei.com>
> ---
> 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..b63adeea1563 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)
>
> +/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
> +#define E1000_MMIO_LEN_MIN 0x10000
> +
> #endif
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
2026-07-15 3:58 [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size Pu Lehui
2026-07-20 1:25 ` Pu Lehui
@ 2026-07-20 9:47 ` Breno Leitao
2026-07-20 11:56 ` Pu Lehui
1 sibling, 1 reply; 7+ messages in thread
From: Breno Leitao @ 2026-07-20 9:47 UTC (permalink / raw)
To: Pu Lehui
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
On Wed, Jul 15, 2026 at 03:58:50AM +0000, Pu Lehui wrote:
> +/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
Why "the largest" in this case?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
2026-07-20 9:47 ` Breno Leitao
@ 2026-07-20 11:56 ` Pu Lehui
2026-07-20 12:53 ` Breno Leitao
0 siblings, 1 reply; 7+ messages in thread
From: Pu Lehui @ 2026-07-20 11:56 UTC (permalink / raw)
To: Breno Leitao
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
On 2026/7/20 17:47, Breno Leitao wrote:
> On Wed, Jul 15, 2026 at 03:58:50AM +0000, Pu Lehui wrote:
>> +/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
>
> Why "the largest" in this case?
Hi Breno,
Thanks for pointing that out. I meant the maximum register offset
accessed by the driver.
IIUC, common e1000e NIC usually have a 128K BAR0. But since I'm not 100%
sure if older NIC might be smaller, I picked 64K as a safe lower limit
because it covers the largest register offset used in the driver's
codebase. If my assumption here is off, I'd really appreciate any
corrections!
And for this comment, how about the follow?
/* Minimum MMIO (BAR0) length to safely cover the maximum register
offset accessed by the driver */
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
2026-07-20 11:56 ` Pu Lehui
@ 2026-07-20 12:53 ` Breno Leitao
2026-07-20 13:16 ` Pu Lehui
2026-07-20 14:46 ` Andrew Lunn
0 siblings, 2 replies; 7+ messages in thread
From: Breno Leitao @ 2026-07-20 12:53 UTC (permalink / raw)
To: Pu Lehui
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
On Mon, Jul 20, 2026 at 07:56:20PM +0800, Pu Lehui wrote:
>
> On 2026/7/20 17:47, Breno Leitao wrote:
> > On Wed, Jul 15, 2026 at 03:58:50AM +0000, Pu Lehui wrote:
> > > +/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
> >
> > Why "the largest" in this case?
>
> Hi Breno,
>
> Thanks for pointing that out. I meant the maximum register offset accessed
> by the driver.
>
> IIUC, common e1000e NIC usually have a 128K BAR0. But since I'm not 100%
> sure if older NIC might be smaller, I picked 64K as a safe lower limit
> because it covers the largest register offset used in the driver's codebase.
> If my assumption here is off, I'd really appreciate any corrections!
>
> And for this comment, how about the follow?
> /* Minimum MMIO (BAR0) length to safely cover the maximum register offset
> accessed by the driver */
Thanks, Would something like this be a bit better?
/*
* Smallest BAR0 that covers every register the driver accesses
*/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
2026-07-20 12:53 ` Breno Leitao
@ 2026-07-20 13:16 ` Pu Lehui
2026-07-20 14:46 ` Andrew Lunn
1 sibling, 0 replies; 7+ messages in thread
From: Pu Lehui @ 2026-07-20 13:16 UTC (permalink / raw)
To: Breno Leitao
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
On 2026/7/20 20:53, Breno Leitao wrote:
> On Mon, Jul 20, 2026 at 07:56:20PM +0800, Pu Lehui wrote:
>>
>> On 2026/7/20 17:47, Breno Leitao wrote:
>>> On Wed, Jul 15, 2026 at 03:58:50AM +0000, Pu Lehui wrote:
>>>> +/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
>>>
>>> Why "the largest" in this case?
>>
>> Hi Breno,
>>
>> Thanks for pointing that out. I meant the maximum register offset accessed
>> by the driver.
>>
>> IIUC, common e1000e NIC usually have a 128K BAR0. But since I'm not 100%
>> sure if older NIC might be smaller, I picked 64K as a safe lower limit
>> because it covers the largest register offset used in the driver's codebase.
>> If my assumption here is off, I'd really appreciate any corrections!
>>
>> And for this comment, how about the follow?
>> /* Minimum MMIO (BAR0) length to safely cover the maximum register offset
>> accessed by the driver */
>
> Thanks, Would something like this be a bit better?
>
> /*
> * Smallest BAR0 that covers every register the driver accesses
> */
>
make sense to me, will respin soon
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
2026-07-20 12:53 ` Breno Leitao
2026-07-20 13:16 ` Pu Lehui
@ 2026-07-20 14:46 ` Andrew Lunn
1 sibling, 0 replies; 7+ messages in thread
From: Andrew Lunn @ 2026-07-20 14:46 UTC (permalink / raw)
To: Breno Leitao
Cc: Pu Lehui, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel
On Mon, Jul 20, 2026 at 05:53:37AM -0700, Breno Leitao wrote:
> On Mon, Jul 20, 2026 at 07:56:20PM +0800, Pu Lehui wrote:
> >
> > On 2026/7/20 17:47, Breno Leitao wrote:
> > > On Wed, Jul 15, 2026 at 03:58:50AM +0000, Pu Lehui wrote:
> > > > +/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
> > >
> > > Why "the largest" in this case?
> >
> > Hi Breno,
> >
> > Thanks for pointing that out. I meant the maximum register offset accessed
> > by the driver.
> >
> > IIUC, common e1000e NIC usually have a 128K BAR0. But since I'm not 100%
> > sure if older NIC might be smaller, I picked 64K as a safe lower limit
> > because it covers the largest register offset used in the driver's codebase.
> > If my assumption here is off, I'd really appreciate any corrections!
> >
> > And for this comment, how about the follow?
> > /* Minimum MMIO (BAR0) length to safely cover the maximum register offset
> > accessed by the driver */
>
> Thanks, Would something like this be a bit better?
>
> /*
> * Smallest BAR0 that covers every register the driver accesses
> */
I would actually reference the highest register. It then becomes
exactly clear where this number comes from. Better still, use the
register #define in the test, along with this comment.
Andrew
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-20 14:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-15 3:58 [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size Pu Lehui
2026-07-20 1:25 ` Pu Lehui
2026-07-20 9:47 ` Breno Leitao
2026-07-20 11:56 ` Pu Lehui
2026-07-20 12:53 ` Breno Leitao
2026-07-20 13:16 ` Pu Lehui
2026-07-20 14:46 ` Andrew Lunn
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.