Add bounds checking code so that any potential out-of-bound
array access is avoided

Signed-off-by: Sergey Temerkhanov <[email protected]>
Reviewed-by: Aleksandr Loktionov <[email protected]>
---
 drivers/net/ethernet/intel/ice/ice_dpll.c | 76 ++++++++++++++---------
 1 file changed, 48 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c 
b/drivers/net/ethernet/intel/ice/ice_dpll.c
index f4d6c247e96e..d0225097cd10 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -760,6 +760,9 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct 
ice_dpll_pin *pin,
        u8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;
        int ret;
 
+       for (int i = 0; i < ICE_DPLL_RCLK_NUM_MAX; i++)
+               pin->state[i] = DPLL_PIN_STATE_DISCONNECTED;
+
        switch (pin_type) {
        case ICE_DPLL_PIN_TYPE_INPUT:
                ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
@@ -769,25 +772,31 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct 
ice_dpll_pin *pin,
                        goto err;
                if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) {
                        if (pin->pin) {
-                               pin->state[pf->dplls.eec.dpll_idx] =
-                                       pin->pin == pf->dplls.eec.active_input ?
-                                       DPLL_PIN_STATE_CONNECTED :
-                                       DPLL_PIN_STATE_SELECTABLE;
-                               pin->state[pf->dplls.pps.dpll_idx] =
-                                       pin->pin == pf->dplls.pps.active_input ?
-                                       DPLL_PIN_STATE_CONNECTED :
-                                       DPLL_PIN_STATE_SELECTABLE;
+                               if (pf->dplls.eec.dpll_idx < 
ICE_DPLL_RCLK_NUM_MAX)
+                                       pin->state[pf->dplls.eec.dpll_idx] =
+                                               pin->pin == 
pf->dplls.eec.active_input ?
+                                               DPLL_PIN_STATE_CONNECTED :
+                                               DPLL_PIN_STATE_SELECTABLE;
+                               if (pf->dplls.pps.dpll_idx < 
ICE_DPLL_RCLK_NUM_MAX)
+                                       pin->state[pf->dplls.pps.dpll_idx] =
+                                               pin->pin == 
pf->dplls.pps.active_input ?
+                                               DPLL_PIN_STATE_CONNECTED :
+                                               DPLL_PIN_STATE_SELECTABLE;
                        } else {
-                               pin->state[pf->dplls.eec.dpll_idx] =
-                                       DPLL_PIN_STATE_SELECTABLE;
-                               pin->state[pf->dplls.pps.dpll_idx] =
-                                       DPLL_PIN_STATE_SELECTABLE;
+                               if (pf->dplls.eec.dpll_idx < 
ICE_DPLL_RCLK_NUM_MAX)
+                                       pin->state[pf->dplls.eec.dpll_idx] =
+                                               DPLL_PIN_STATE_SELECTABLE;
+                               if (pf->dplls.pps.dpll_idx < 
ICE_DPLL_RCLK_NUM_MAX)
+                                       pin->state[pf->dplls.pps.dpll_idx] =
+                                               DPLL_PIN_STATE_SELECTABLE;
                        }
                } else {
-                       pin->state[pf->dplls.eec.dpll_idx] =
-                               DPLL_PIN_STATE_DISCONNECTED;
-                       pin->state[pf->dplls.pps.dpll_idx] =
-                               DPLL_PIN_STATE_DISCONNECTED;
+                       if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+                               pin->state[pf->dplls.eec.dpll_idx] =
+                                       DPLL_PIN_STATE_DISCONNECTED;
+                       if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+                               pin->state[pf->dplls.pps.dpll_idx] =
+                                       DPLL_PIN_STATE_DISCONNECTED;
                }
                break;
        case ICE_DPLL_PIN_TYPE_OUTPUT:
@@ -799,19 +808,23 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct 
ice_dpll_pin *pin,
 
                parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
                if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
-                       pin->state[pf->dplls.eec.dpll_idx] =
-                               parent == pf->dplls.eec.dpll_idx ?
-                               DPLL_PIN_STATE_CONNECTED :
-                               DPLL_PIN_STATE_DISCONNECTED;
-                       pin->state[pf->dplls.pps.dpll_idx] =
-                               parent == pf->dplls.pps.dpll_idx ?
-                               DPLL_PIN_STATE_CONNECTED :
-                               DPLL_PIN_STATE_DISCONNECTED;
+                       if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+                               pin->state[pf->dplls.eec.dpll_idx] =
+                                       parent == pf->dplls.eec.dpll_idx ?
+                                       DPLL_PIN_STATE_CONNECTED :
+                                       DPLL_PIN_STATE_DISCONNECTED;
+                       if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+                               pin->state[pf->dplls.pps.dpll_idx] =
+                                       parent == pf->dplls.pps.dpll_idx ?
+                                       DPLL_PIN_STATE_CONNECTED :
+                                       DPLL_PIN_STATE_DISCONNECTED;
                } else {
-                       pin->state[pf->dplls.eec.dpll_idx] =
-                               DPLL_PIN_STATE_DISCONNECTED;
-                       pin->state[pf->dplls.pps.dpll_idx] =
-                               DPLL_PIN_STATE_DISCONNECTED;
+                       if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+                               pin->state[pf->dplls.eec.dpll_idx] =
+                                       DPLL_PIN_STATE_DISCONNECTED;
+                       if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+                               pin->state[pf->dplls.pps.dpll_idx] =
+                                       DPLL_PIN_STATE_DISCONNECTED;
                }
                break;
        case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
@@ -5180,6 +5193,13 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool 
cgu)
 
        de->dpll_idx = abilities.eec_dpll_idx;
        dp->dpll_idx = abilities.pps_dpll_idx;
+       if (de->dpll_idx >= ICE_DPLL_RCLK_NUM_MAX ||
+           dp->dpll_idx >= ICE_DPLL_RCLK_NUM_MAX) {
+               dev_err(ice_pf_to_dev(pf),
+                       "invalid dpll_idx in cgu abilities: eec=%u, pps=%u\n",
+                       de->dpll_idx, dp->dpll_idx);
+               return -EINVAL;
+       }
        d->num_inputs = abilities.num_inputs;
        d->num_outputs = abilities.num_outputs;
        d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
-- 
2.53.0

Reply via email to