From: Paul Greenwalt <[email protected]> It's possible that an NVM with an invalid tlv_len could cause an integer overflow of next_tlv which can result an infinite loop.
Fix this issue by changing next_tlv from u16 to u32 to prevent overflow. Also check that tlv_len is valid and less than pfa_len. Signed-off-by: Paul Greenwalt <[email protected]> Signed-off-by: Jacob Keller <[email protected]> --- drivers/net/ethernet/intel/ice/ice_nvm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.c b/drivers/net/ethernet/intel/ice/ice_nvm.c index 84eab92dc03c..9e58d319355f 100644 --- a/drivers/net/ethernet/intel/ice/ice_nvm.c +++ b/drivers/net/ethernet/intel/ice/ice_nvm.c @@ -441,7 +441,7 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, u16 module_type) { u16 pfa_len, pfa_ptr; - u16 next_tlv; + u32 next_tlv; int status; status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr); @@ -458,7 +458,7 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, * of TLVs to find the requested one. */ next_tlv = pfa_ptr + 1; - while (next_tlv < pfa_ptr + pfa_len) { + while (next_tlv < ((u32)pfa_ptr + pfa_len)) { u16 tlv_sub_module_type; u16 tlv_len; @@ -474,6 +474,10 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n"); break; } + if (tlv_len > pfa_len) { + ice_debug(hw, ICE_DBG_INIT, "Invalid TLV length.\n"); + return -EINVAL; + } if (tlv_sub_module_type == module_type) { if (tlv_len) { *module_tlv = next_tlv; --- base-commit: 83e93942796db58652288f0391ac00072401816f change-id: 20240516-iwl-net-2024-05-16-fix-nvm-tlv-issue-99ebb2c55c52 Best regards, -- Jacob Keller <[email protected]>
