[PATCH iwl-next] ixgbe: add bounds check for debugfs register access
From: Aleksandr Loktionov <hidden>
Date: 2026-03-27 07:30:50
Also in:
intel-wired-lan
Subsystem:
intel ethernet drivers, networking drivers, the rest · Maintainers:
Tony Nguyen, Przemek Kitszel, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
From: Paul Greenwalt <redacted> 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(). Signed-off-by: Paul Greenwalt <redacted> Signed-off-by: Aleksandr Loktionov <redacted> --- 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", ®, &value); - if (cnt == 2) { + /* check format and bounds check register access */ + 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", ®); - if (cnt == 1) { + /* check format and bounds check register access */ + 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