git: c7f0473df2ed - stable/15 - ixgbe: Validate EEPROM checksum section bounds

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Mon, 24 Aug 2026 00:53:46 UTC
The branch stable/15 has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=c7f0473df2ed901f9c6559fb152c457dc4296c13

commit c7f0473df2ed901f9c6559fb152c457dc4296c13
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-10 15:09:41 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-24 00:51:04 +0000

    ixgbe: Validate EEPROM checksum section bounds
    
    The generic checksum walker trusts NVM section pointers and lengths and
    iterates with a 16-bit index.  A corrupt section that crosses the end of
    the EEPROM can wrap the index and leave the driver in an effectively
    unbounded read loop during attach.
    
    Validate each non-empty section against the discovered EEPROM word size
    before reading it, and use widened arithmetic for the inclusive end and
    iterator.
    
    (cherry picked from commit be3e1068ea8699fb719691453899ca20a601fe1d)
---
 sys/dev/ixgbe/ixgbe_common.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c
index c4e78a048b49..38951c09fb27 100644
--- a/sys/dev/ixgbe/ixgbe_common.c
+++ b/sys/dev/ixgbe/ixgbe_common.c
@@ -2221,7 +2221,8 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
 s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
 {
 	u16 i;
-	u16 j;
+	u32 j;
+	u32 word_end;
 	u16 checksum = 0;
 	u16 length = 0;
 	u16 pointer = 0;
@@ -2248,6 +2249,10 @@ s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
 		/* If the pointer seems invalid */
 		if (pointer == 0xFFFF || pointer == 0)
 			continue;
+		if (pointer >= hw->eeprom.word_size) {
+			DEBUGOUT("EEPROM pointer outside word range\n");
+			return IXGBE_ERR_EEPROM;
+		}
 
 		if (hw->eeprom.ops.read(hw, pointer, &length)) {
 			DEBUGOUT("EEPROM read failed\n");
@@ -2256,9 +2261,14 @@ s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
 
 		if (length == 0xFFFF || length == 0)
 			continue;
+		if (length >= hw->eeprom.word_size - pointer) {
+			DEBUGOUT("EEPROM section outside word range\n");
+			return IXGBE_ERR_EEPROM;
+		}
 
-		for (j = pointer + 1; j <= pointer + length; j++) {
-			if (hw->eeprom.ops.read(hw, j, &word)) {
+		word_end = (u32)pointer + length;
+		for (j = (u32)pointer + 1; j <= word_end; j++) {
+			if (hw->eeprom.ops.read(hw, (u16)j, &word)) {
 				DEBUGOUT("EEPROM read failed\n");
 				return IXGBE_ERR_EEPROM;
 			}