Skip to content

Commit ebe41da

Browse files
ihuguetkuba-moo
authored andcommitted
sfc: fix use after free when disabling sriov
Use after free is detected by kfence when disabling sriov. What was read after being freed was vf->pci_dev: it was freed from pci_disable_sriov and later read in efx_ef10_sriov_free_vf_vports, called from efx_ef10_sriov_free_vf_vswitching. Set the pointer to NULL at release time to not trying to read it later. Reproducer and dmesg log (note that kfence doesn't detect it every time): $ echo 1 > /sys/class/net/enp65s0f0np0/device/sriov_numvfs $ echo 0 > /sys/class/net/enp65s0f0np0/device/sriov_numvfs BUG: KFENCE: use-after-free read in efx_ef10_sriov_free_vf_vswitching+0x82/0x170 [sfc] Use-after-free read at 0x00000000ff3c1ba5 (in kfence-#224): efx_ef10_sriov_free_vf_vswitching+0x82/0x170 [sfc] efx_ef10_pci_sriov_disable+0x38/0x70 [sfc] efx_pci_sriov_configure+0x24/0x40 [sfc] sriov_numvfs_store+0xfe/0x140 kernfs_fop_write_iter+0x11c/0x1b0 new_sync_write+0x11f/0x1b0 vfs_write+0x1eb/0x280 ksys_write+0x5f/0xe0 do_syscall_64+0x5c/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xae kfence-#224: 0x00000000edb8ef95-0x00000000671f5ce1, size=2792, cache=kmalloc-4k allocated by task 6771 on cpu 10 at 3137.860196s: pci_alloc_dev+0x21/0x60 pci_iov_add_virtfn+0x2a2/0x320 sriov_enable+0x212/0x3e0 efx_ef10_sriov_configure+0x67/0x80 [sfc] efx_pci_sriov_configure+0x24/0x40 [sfc] sriov_numvfs_store+0xba/0x140 kernfs_fop_write_iter+0x11c/0x1b0 new_sync_write+0x11f/0x1b0 vfs_write+0x1eb/0x280 ksys_write+0x5f/0xe0 do_syscall_64+0x5c/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xae freed by task 6771 on cpu 12 at 3170.991309s: device_release+0x34/0x90 kobject_cleanup+0x3a/0x130 pci_iov_remove_virtfn+0xd9/0x120 sriov_disable+0x30/0xe0 efx_ef10_pci_sriov_disable+0x57/0x70 [sfc] efx_pci_sriov_configure+0x24/0x40 [sfc] sriov_numvfs_store+0xfe/0x140 kernfs_fop_write_iter+0x11c/0x1b0 new_sync_write+0x11f/0x1b0 vfs_write+0x1eb/0x280 ksys_write+0x5f/0xe0 do_syscall_64+0x5c/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xae Fixes: 3c5eb87 ("sfc: create vports for VFs and assign random MAC addresses") Reported-by: Yanghang Liu <[email protected]> Signed-off-by: Íñigo Huguet <[email protected]> Acked-by: Martin Habets <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent b11e5f6 commit ebe41da

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

drivers/net/ethernet/sfc/ef10_sriov.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,19 +408,23 @@ static int efx_ef10_pci_sriov_enable(struct efx_nic *efx, int num_vfs)
408408
static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force)
409409
{
410410
struct pci_dev *dev = efx->pci_dev;
411+
struct efx_ef10_nic_data *nic_data = efx->nic_data;
411412
unsigned int vfs_assigned = pci_vfs_assigned(dev);
412-
int rc = 0;
413+
int i, rc = 0;
413414

414415
if (vfs_assigned && !force) {
415416
netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; "
416417
"please detach them before disabling SR-IOV\n");
417418
return -EBUSY;
418419
}
419420

420-
if (!vfs_assigned)
421+
if (!vfs_assigned) {
422+
for (i = 0; i < efx->vf_count; i++)
423+
nic_data->vf[i].pci_dev = NULL;
421424
pci_disable_sriov(dev);
422-
else
425+
} else {
423426
rc = -EBUSY;
427+
}
424428

425429
efx_ef10_sriov_free_vf_vswitching(efx);
426430
efx->vf_count = 0;

0 commit comments

Comments
 (0)