aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Bowling <kbowling@FreeBSD.org>2026-08-10 15:09:41 +0000
committerKevin Bowling <kbowling@FreeBSD.org>2026-08-10 16:33:12 +0000
commitbe3e1068ea8699fb719691453899ca20a601fe1d (patch)
tree3563032ab2c28d9e4afafc8a23f4ab40ebd9a7fb
parent660099c985e8bfc931b01398715441c90cf0d4db (diff)
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
-rw-r--r--sys/dev/ixgbe/ixgbe_common.c16
1 files 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;
}