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; }