[PATCH iwl-net v2 2/6] ixgbe: add bounds check for debugfs register access

Aleksandr Loktionov
2026-04-08T13:11:59Z

From: Paul Greenwalt <paul.greenwalt@intel.com>

Prevent out-of-bounds MMIO accesses triggered through user-controlled
register offsets. IXGBE_HFDR (0x15FE8) is the highest valid MMIO
register in the ixgbe register map; any offset beyond it would address
unmapped memory.

Add a defense-in-depth check at two levels:

1. ixgbe_read_reg() -- the noinline register read accessor. A
WARN_ON_ONCE() guard here catches any future code path (including
ioctl extensions) that might inadvertently pass an out-of-range
offset without relying on higher layers to catch it first.
ixgbe_write_reg() is a static inline called from the TX/RX hot path;
adding WARN_ON_ONCE there would inline the check at every call site,
so only the read path gets this guard.

2. ixgbe_dbg_reg_ops_write() -- the debugfs 'reg_ops' interface is the
only current path where a raw, user-supplied offset enters the driver.
Gating it before invoking the register accessors provides a clean,
user-visible failure (silent ignore with no kernel splat) for
deliberately malformed debugfs writes.

Add a reg <= IXGBE_HFDR guard to both the read and write paths in
ixgbe_dbg_reg_ops_write(), and a WARN_ON_ONCE + early-return guard to
ixgbe_read_reg().

Fixes: 91fbd8f081e2 ("ixgbe: added reg_ops file to debugfs")
Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
v1 -> v2:
- Add Fixes: tag; reroute from iwl-next to iwl-net (security-relevant
hardening for user-controllable out-of-bounds MMIO).

drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c | 6 ++++--
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 ++
2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
index 5b1cf49d..a6a19c0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
@@ -86,7 +86,8 @@ static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp,
u32 reg, value;
int cnt;
cnt = sscanf(&ixgbe_dbg_reg_ops_buf[5], "%x %x", &reg, &value);
- if (cnt == 2) {
+ /* bounds-check register offset */
+ if (cnt == 2 && reg <= IXGBE_HFDR) {
IXGBE_WRITE_REG(&adapter->hw, reg, value);
value = IXGBE_READ_REG(&adapter->hw, reg);
e_dev_info("write: 0x%08x = 0x%08x\n", reg, value);
@@ -97,7 +98,8 @@ static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp,
u32 reg, value;
int cnt;
cnt = sscanf(&ixgbe_dbg_reg_ops_buf[4], "%x", &reg);
- if (cnt == 1) {
+ /* bounds-check register offset */
+ if (cnt == 1 && reg <= IXGBE_HFDR) {
value = IXGBE_READ_REG(&adapter->hw, reg);
e_dev_info("read 0x%08x = 0x%08x\n", reg, value);
} else {

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 210c7b9..4a1f3c2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -354,4 +354,6 @@ u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg)
if (ixgbe_removed(reg_addr))
return IXGBE_FAILED_READ_REG;
+ if (WARN_ON_ONCE(reg > IXGBE_HFDR))
+ return IXGBE_FAILED_READ_REG;
if (unlikely(hw->phy.nw_mng_if_sel &
IXGBE_NW_MNG_IF_SEL_SGMII_ENABLE)) {
--
2.52.0