Skip to content

Commit 79990cf

Browse files
Marcin Szycikkuba-moo
authored andcommitted
ice: Fix deinitializing VF in error path
If ice_ena_vfs() fails after calling ice_create_vf_entries(), it frees all VFs without removing them from snapshot PF-VF mailbox list, leading to list corruption. Reproducer: devlink dev eswitch set $PF1_PCI mode switchdev ip l s $PF1 up ip l s $PF1 promisc on sleep 1 echo 1 > /sys/class/net/$PF1/device/sriov_numvfs sleep 1 echo 1 > /sys/class/net/$PF1/device/sriov_numvfs Trace (minimized): list_add corruption. next->prev should be prev (ffff8882e241c6f0), but was 0000000000000000. (next=ffff888455da1330). kernel BUG at lib/list_debug.c:29! RIP: 0010:__list_add_valid_or_report+0xa6/0x100 ice_mbx_init_vf_info+0xa7/0x180 [ice] ice_initialize_vf_entry+0x1fa/0x250 [ice] ice_sriov_configure+0x8d7/0x1520 [ice] ? __percpu_ref_switch_mode+0x1b1/0x5d0 ? __pfx_ice_sriov_configure+0x10/0x10 [ice] Sometimes a KASAN report can be seen instead with a similar stack trace: BUG: KASAN: use-after-free in __list_add_valid_or_report+0xf1/0x100 VFs are added to this list in ice_mbx_init_vf_info(), but only removed in ice_free_vfs(). Move the removing to ice_free_vf_entries(), which is also being called in other places where VFs are being removed (including ice_free_vfs() itself). Fixes: 8cd8a6b ("ice: move VF overflow message count into struct ice_mbx_vf_info") Reported-by: Sujai Buvaneswaran <[email protected]> Closes: https://lore.kernel.org/intel-wired-lan/PH0PR11MB50138B635F2E5CEB7075325D961F2@PH0PR11MB5013.namprd11.prod.outlook.com Reviewed-by: Martyna Szapar-Mudlaw <[email protected]> Signed-off-by: Marcin Szycik <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Sujai Buvaneswaran <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5568e4c commit 79990cf

File tree

3 files changed

+10
-4
lines changed

3 files changed

+10
-4
lines changed

drivers/net/ethernet/intel/ice/ice_sriov.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static void ice_free_vf_entries(struct ice_pf *pf)
3636

3737
hash_for_each_safe(vfs->table, bkt, tmp, vf, entry) {
3838
hash_del_rcu(&vf->entry);
39+
ice_deinitialize_vf_entry(vf);
3940
ice_put_vf(vf);
4041
}
4142
}
@@ -193,10 +194,6 @@ void ice_free_vfs(struct ice_pf *pf)
193194
wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx));
194195
}
195196

196-
/* clear malicious info since the VF is getting released */
197-
if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
198-
list_del(&vf->mbx_info.list_entry);
199-
200197
mutex_unlock(&vf->cfg_lock);
201198
}
202199

drivers/net/ethernet/intel/ice/ice_vf_lib.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,14 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
10361036
mutex_init(&vf->cfg_lock);
10371037
}
10381038

1039+
void ice_deinitialize_vf_entry(struct ice_vf *vf)
1040+
{
1041+
struct ice_pf *pf = vf->pf;
1042+
1043+
if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
1044+
list_del(&vf->mbx_info.list_entry);
1045+
}
1046+
10391047
/**
10401048
* ice_dis_vf_qs - Disable the VF queues
10411049
* @vf: pointer to the VF structure

drivers/net/ethernet/intel/ice/ice_vf_lib_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#endif
2525

2626
void ice_initialize_vf_entry(struct ice_vf *vf);
27+
void ice_deinitialize_vf_entry(struct ice_vf *vf);
2728
void ice_dis_vf_qs(struct ice_vf *vf);
2829
int ice_check_vf_init(struct ice_vf *vf);
2930
enum virtchnl_status_code ice_err_to_virt_err(int err);

0 commit comments

Comments
 (0)