git: be3e1068ea86 - main - ixgbe: Validate EEPROM checksum section bounds

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.current.scm
Message-ID <[email protected]>
The branch main has been updated by kbowling:

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

commit be3e1068ea8699fb719691453899ca20a601fe1d
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-10 15:09:41 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-10 16:33:12 +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.
    
    MFC after:      2 weeks
---
 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 5965e1146175..3ee6885dcad9 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;
 			}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.