Coverity reports multiple issues (INTEGER_OVERFLOW and BAD_SHIFT)
in the e56 backplane code. The root cause is that 'lane_num' is
initialized to 0 and only set in the switch statement based on
the link speed. The default case simply logs and breaks, leaving
lane_num as 0 for unsupported speeds.
This leads to unsigned underflow when evaluating 'lane_num - 1'
in GENMASK(lane_num - 1, 0), and undefined behavior when the
resulting mask is used in shift operations.
Fix by returning -EINVAL immediately in the default case of
txgbe_e56_cl72_training(), preventing any invalid speed from
proceeding further. Also add error handling at the call site
txgbe_handle_e56_bkp_an73_flow() to check the return value and
propagate the error.
For txgbe_e56_rxs_osc_init_for_temp_track_range(), no additional
check is added because:
1. It is called from txgbe_e56_cl72_training() after lane_num
has been validated to one of the legal values (1, 2, 4, or 8).
2. The other caller, txgbe_e56_set_phy_link_mode(), passes a
fixed speed of 10 (lane_num = 1), which is also valid.
Coverity issue: 504598, 504602, 504613
Fixes: 234ce0d1fa9d ("net/txgbe: fix link stability for Amber-Lite backplane
mode")
Cc: [email protected]
Signed-off-by: Zaiyu Wang <[email protected]>
---
drivers/net/txgbe/base/txgbe_e56_bp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/txgbe/base/txgbe_e56_bp.c
b/drivers/net/txgbe/base/txgbe_e56_bp.c
index f8b39a0c7e..d376d918df 100644
--- a/drivers/net/txgbe/base/txgbe_e56_bp.c
+++ b/drivers/net/txgbe/base/txgbe_e56_bp.c
@@ -2432,7 +2432,7 @@ static int txgbe_e56_cl72_training(struct txgbe_hw *hw)
break;
default:
BP_LOG("%s %d :Invalid speed\n", __func__, __LINE__);
- break;
+ return -EINVAL;
}
BP_LOG("2.3 Wait %dG KR phy mode init ....\n", bylinkmode);
@@ -2583,6 +2583,10 @@ int txgbe_handle_e56_bkp_an73_flow(struct txgbe_hw *hw)
}
status = txgbe_e56_cl72_training(hw);
+ if (status) {
+ BP_LOG("CL72 training failed, status = %d\n", status);
+ return status;
+ }
rdata = rd32_ephy(hw, E56PHY_RXS_IDLE_DETECT_1_ADDR);
set_fields_e56(&rdata, E56PHY_RXS_IDLE_DETECT_1_IDLE_TH_ADC_PEAK_MAX,
0x28);
--
2.21.0.windows.1