From: Rengarajan S rengarajan.s@microchip.com
[ Upstream commit 3b9935586a9b54d2da27901b830d3cf46ad66a1e ]
Maximum OTP and EEPROM size for hearthstone PCI1xxxx devices are 8 Kb and 64 Kb respectively. Adjust max size definitions and return correct EEPROM length based on device. Also prevent out-of-bound read/write.
Signed-off-by: Rengarajan S rengarajan.s@microchip.com Link: https://patch.msgid.link/20250523173326.18509-1-rengarajan.s@microchip.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
**YES** This commit should be backported to stable kernel trees. Here's my detailed analysis: ## Security Fix Classification This commit addresses a **security vulnerability** by adding bounds checking to prevent out-of-bounds reads and writes in EEPROM/OTP operations for PCI1xxxx devices. The commit explicitly states "Also prevent out-of- bound read/write" in the commit message, making this a clear security fix. ## Code Analysis Details The commit adds critical bounds checking in four functions: 1. **`lan743x_hs_otp_read()`** - Adds `if (offset + length > MAX_HS_OTP_SIZE) return -EINVAL;` 2. **`lan743x_hs_otp_write()`** - Adds `if (offset + length > MAX_HS_OTP_SIZE) return -EINVAL;` 3. **`lan743x_hs_eeprom_read()`** - Adds `if (offset + length > MAX_HS_EEPROM_SIZE) return -EINVAL;` 4. **`lan743x_hs_eeprom_write()`** - Adds `if (offset + length > MAX_HS_EEPROM_SIZE) return -EINVAL;` The new size limits are: - `MAX_HS_OTP_SIZE = 8 linux 1024` (8KB) - `MAX_HS_EEPROM_SIZE = 64 linux 1024` (64KB) ## Vulnerability Impact Without these bounds checks, the functions could perform out-of-bounds memory operations when: - User- space provides large `offset` or `length` values via ethtool EEPROM/OTP access - The hardware access operations could read/write beyond the intended EEPROM/OTP memory regions - This could potentially lead to memory corruption or information disclosure ## Context from Kernel Tree Analysis The kernel tree analysis confirms that: - The original LAN743x functions already had proper bounds checking - The newer Hearthstone PCI1xxxx variants lacked these critical safety checks - This creates an inconsistency where newer hardware had weaker security protections - The commit message explicitly mentions preventing "out-of-bound read/write" ## Backport Suitability Criteria ✅ **Fixes important security vulnerability**: Prevents out-of-bounds memory access ✅ **Small and contained change**: Only adds 4 simple bounds checks, minimal code change ✅ **Low regression risk**: Simple validation logic that only rejects invalid inputs ✅ **Clear side effects**: Only affects invalid operations that should fail anyway ✅ **No architectural changes**: Maintains existing function interfaces and behavior ✅ **Affects critical subsystem**: Network driver EEPROM/OTP access with potential security implications ## Comparison with Similar Commits The similar commits shown all have "Backport Status: NO" but they are primarily feature additions (new EEPROM support, SGMII support, performance improvements). This commit is fundamentally different as it's a **security fix** addressing missing bounds validation, not a new feature. ## Conclusion This commit represents a textbook example of a stable tree backport candidate: it's a small, targeted security fix that prevents out-of- bounds memory access with minimal code changes and negligible regression risk. The absence of bounds checking in the Hearthstone variants while present in the original LAN743x functions suggests this was an oversight that needs correction across all supported kernel versions.
.../net/ethernet/microchip/lan743x_ethtool.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c index 1a1cbd034eda0..2acd9c3531dea 100644 --- a/drivers/net/ethernet/microchip/lan743x_ethtool.c +++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c @@ -18,6 +18,8 @@ #define EEPROM_MAC_OFFSET (0x01) #define MAX_EEPROM_SIZE (512) #define MAX_OTP_SIZE (1024) +#define MAX_HS_OTP_SIZE (8 * 1024) +#define MAX_HS_EEPROM_SIZE (64 * 1024) #define OTP_INDICATOR_1 (0xF3) #define OTP_INDICATOR_2 (0xF7)
@@ -272,6 +274,9 @@ static int lan743x_hs_otp_read(struct lan743x_adapter *adapter, u32 offset, int ret; int i;
+ if (offset + length > MAX_HS_OTP_SIZE) + return -EINVAL; + ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (ret < 0) return ret; @@ -320,6 +325,9 @@ static int lan743x_hs_otp_write(struct lan743x_adapter *adapter, u32 offset, int ret; int i;
+ if (offset + length > MAX_HS_OTP_SIZE) + return -EINVAL; + ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (ret < 0) return ret; @@ -497,6 +505,9 @@ static int lan743x_hs_eeprom_read(struct lan743x_adapter *adapter, u32 val; int i;
+ if (offset + length > MAX_HS_EEPROM_SIZE) + return -EINVAL; + retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (retval < 0) return retval; @@ -539,6 +550,9 @@ static int lan743x_hs_eeprom_write(struct lan743x_adapter *adapter, u32 val; int i;
+ if (offset + length > MAX_HS_EEPROM_SIZE) + return -EINVAL; + retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (retval < 0) return retval; @@ -604,9 +618,9 @@ static int lan743x_ethtool_get_eeprom_len(struct net_device *netdev) struct lan743x_adapter *adapter = netdev_priv(netdev);
if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) - return MAX_OTP_SIZE; + return adapter->is_pci11x1x ? MAX_HS_OTP_SIZE : MAX_OTP_SIZE;
- return MAX_EEPROM_SIZE; + return adapter->is_pci11x1x ? MAX_HS_EEPROM_SIZE : MAX_EEPROM_SIZE; }
static int lan743x_ethtool_get_eeprom(struct net_device *netdev,