[PATCH 5/8] net/ice: fix DCF QoS bandwidth replay config leak

Bruce Richardson bruce.richardson at intel.com
Fri Nov 6 13:06:17 CET 2026


On Thu, Nov 05, 2026 at 09:47:22AM +0000, Anurag Mandal wrote:
> ice_dcf_hierarchy_commit() keeps a copy of the bandwidth config
> of each VF, and of the TC nodes, in qos_bw_cfg[] to replay it
> after a VF reset.
> Each commit allocates new copies without freeing the old ones,
> and ice_dcf_uninit_hw() frees the array but not the copies, so
> they also leak on close and reset.
> 
> Free the old copy before allocating a new one, and free all copies
> in ice_dcf_uninit_hw().
> 
> Fixes: 931ee54072b1 ("net/ice: support QoS bandwidth config after VF reset in DCF")
> Fixes: 775a25a372f5 ("net/ice: clear QoS bandwidth on DCF close")
> Cc: stable at dpdk.org
> 
> Signed-off-by: Anurag Mandal <anurag.mandal at intel.com>
> ---
>  drivers/net/intel/ice/ice_dcf.c       | 6 ++++++
>  drivers/net/intel/ice/ice_dcf_sched.c | 2 ++
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/net/intel/ice/ice_dcf.c b/drivers/net/intel/ice/ice_dcf.c
> index 09fcf6454f..c2b557d0da 100644
> --- a/drivers/net/intel/ice/ice_dcf.c
> +++ b/drivers/net/intel/ice/ice_dcf.c
> @@ -884,6 +884,7 @@ ice_dcf_uninit_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
>  {
>  	struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
>  	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
> +	uint16_t i;
>  
>  	if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS)
>  		if (hw->tm_conf.committed) {
> @@ -919,6 +920,11 @@ ice_dcf_uninit_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
>  	rte_free(hw->rss_key);
>  	hw->rss_key = NULL;
>  
> +	if (hw->qos_bw_cfg != NULL) {
> +		for (i = 0; i < hw->num_vfs; i++)
> +			rte_free(hw->qos_bw_cfg[i]);
> +	}
> +
>  	rte_free(hw->qos_bw_cfg);
>  	hw->qos_bw_cfg = NULL;
>  
> diff --git a/drivers/net/intel/ice/ice_dcf_sched.c b/drivers/net/intel/ice/ice_dcf_sched.c
> index de28019c5b..f8755c7dcb 100644
> --- a/drivers/net/intel/ice/ice_dcf_sched.c
> +++ b/drivers/net/intel/ice/ice_dcf_sched.c
> @@ -813,6 +813,7 @@ static int ice_dcf_hierarchy_commit(struct rte_eth_dev *dev,
>  		if (ret_val)
>  			goto fail_clear;
>  
> +		rte_free(hw->qos_bw_cfg[vf_id]);
>  		hw->qos_bw_cfg[vf_id] = rte_zmalloc("vf_bw_cfg", size, 0);
>  		if (!hw->qos_bw_cfg[vf_id]) {
>  			ret_val = ICE_ERR_NO_MEMORY;
> @@ -840,6 +841,7 @@ static int ice_dcf_hierarchy_commit(struct rte_eth_dev *dev,
>  		goto fail_clear;
>  
>  	/* store TC node bw configuration */
> +	rte_free(hw->qos_bw_cfg[ICE_DCF_VFID]);
>  	hw->qos_bw_cfg[ICE_DCF_VFID] = rte_zmalloc("tc_bw_cfg", size, 0);
>  	if (!hw->qos_bw_cfg[ICE_DCF_VFID]) {
>  		ret_val = ICE_ERR_NO_MEMORY;
> -- 
> 2.25.1
> 

AI review flags this:

The new free can race with VF-reset replay and cause a use-after-free. The
reset worker calls ice_dcf_parent.c:152-153, which passes the cached buffer
to the virtchnl command (ice_dcf_sched.c:681-686); meanwhile the hierarchy
commit frees and replaces that buffer (ice_dcf_sched.c:816-823). The reset
worker’s vsi_update_lock does not protect the commit path. Serialize
replacement with replay, or copy the replay data while holding a shared
lock.


More information about the stable mailing list