[PATCH] net/i40e: fix FDIR flexible payload issues
sandeep.penigalapati at intel.com
sandeep.penigalapati at intel.com
Wed Jul 8 02:20:45 CEST 2026
From: Sandeep Penigalapati <sandeep.penigalapati at intel.com>
This fixes two issues in the i40e Flow Director flexible payload path.
The bitmask array bound was checked after the write to
bitmask[nb_bitmask], allowing a one-slot out-of-bounds write when the
number of partial-mask words exceeds I40E_FDIR_BITMASK_NUM_WORD. Move
the check before the write and use '>=' so the array is never indexed
out of bounds.
In addition, i40e_flow_set_fdir_flex_pit() programs the global GLQF_ORT
register, which is shared by all PFs on the NIC. It was called before
the flex mask was validated, so a rule that is later rejected still left
the global register modified, affecting other PFs. Validate the flex
mask first and only touch the hardware registers once it has passed.
Fixes: 6ced3dd72f5f ("net/i40e: support flexible payload parsing for FDIR")
Cc: stable at dpdk.org
Signed-off-by: Sandeep Penigalapati <sandeep.penigalapati at intel.com>
---
drivers/net/intel/i40e/i40e_fdir.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/net/intel/i40e/i40e_fdir.c b/drivers/net/intel/i40e/i40e_fdir.c
index ad256a5a11..8a233f8a97 100644
--- a/drivers/net/intel/i40e/i40e_fdir.c
+++ b/drivers/net/intel/i40e/i40e_fdir.c
@@ -1230,12 +1230,12 @@ i40e_flow_store_flex_mask(struct i40e_pf *pf,
flex_mask.word_mask |=
I40E_FLEX_WORD_MASK(i / sizeof(uint16_t));
if (mask_tmp != UINT16_MAX) {
+ if (nb_bitmask >= I40E_FDIR_BITMASK_NUM_WORD)
+ return -1;
flex_mask.bitmask[nb_bitmask].mask = ~mask_tmp;
flex_mask.bitmask[nb_bitmask].offset =
i / sizeof(uint16_t);
nb_bitmask++;
- if (nb_bitmask > I40E_FDIR_BITMASK_NUM_WORD)
- return -1;
}
}
}
@@ -1488,15 +1488,17 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
}
}
- if (cfg_flex_pit)
- i40e_flow_set_fdir_flex_pit(pf, layer_idx,
- filter->input.flow_ext.raw_id);
-
/* Store flex mask to SW */
for (i = 0; i < I40E_FDIR_MAX_FLEX_LEN; i++)
flex_mask[i] =
filter->input.flow_ext.flex_mask[i];
+ /* Validate the flex mask before writing any hardware
+ * register. i40e_flow_set_fdir_flex_pit() below programs
+ * the global GLQF_ORT register, which is shared by all
+ * PFs on the NIC, so it must not be touched for a rule
+ * that is going to be rejected.
+ */
ret = i40e_flow_store_flex_mask(pf, pctype, flex_mask);
if (ret == -1) {
PMD_DRV_LOG(ERR, "Exceed maximal"
@@ -1506,9 +1508,14 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
PMD_DRV_LOG(ERR, "Conflict with the"
" first flexible rule");
return -EINVAL;
- } else if (ret == 0) {
- i40e_flow_set_fdir_flex_msk(pf, pctype);
}
+
+ if (cfg_flex_pit)
+ i40e_flow_set_fdir_flex_pit(pf, layer_idx,
+ filter->input.flow_ext.raw_id);
+
+ if (ret == 0)
+ i40e_flow_set_fdir_flex_msk(pf, pctype);
}
ret = i40e_sw_fdir_filter_insert(pf, &check_filter);
--
2.27.0
More information about the stable
mailing list