diff mbox series

[net] ice: Fix use-after-free

Message ID 20220404100615.23525-1-ivecera@redhat.com (mailing list archive)
State Awaiting Upstream
Delegated to: Netdev Maintainers
Headers show
Series [net] ice: Fix use-after-free | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 9 of 9 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 9 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Ivan Vecera April 4, 2022, 10:06 a.m. UTC
When CONFIG_RFS_ACCEL is enabled the driver uses CPU affinity
reverse-maps that set CPU affinity notifier in the background.

If the interface is put down then ice_vsi_free_irq() is called
via ice_vsi_close() and this clears affinity notifiers of IRQs
associated with the VSI and old notifier's release callback
is called - for this case this is cpu_rmap_release() that
frees allocated cpu_rmap.

During device removal (ice_remove()) free_irq_cpu_rmap() is called
and it tries to free already de-allocated cpu_rmap.

Do not clear IRQ affinity notifier in ice_vsi_free_irq() when
CONFIG_RFS_ACCEL is enabled. This is a code-path that
commit 28bf26724fdb ("ice: Implement aRFS") forgot to handle.

Reproducer:
[root@host ~]# ip link set ens7f0 up
[root@host ~]# ip link set ens7f0 down
[root@host ~]# rmmod ice

Result:
[  538.173276] =================================================================
[  538.180615] BUG: KASAN: use-after-free in free_irq_cpu_rmap+0x13b/0x173
[  538.187236] Read of size 4 at addr ff110022d1f9e300 by task rmmod/16218
[  538.193849]
[  538.195350] CPU: 0 PID: 16218 Comm: rmmod Kdump: loaded Not tainted 4.18.0-31
[  538.205613] Hardware name: Dell Inc. PowerEdge R750/06V45N, BIOS 1.4.4 10/071
[  538.213089] Call Trace:
[  538.215544]  dump_stack+0x5c/0x80
[  538.218873]  print_address_description.constprop.6+0x1a/0x150
[  538.233182]  kasan_report.cold.11+0x7f/0x118
[  538.241739]  free_irq_cpu_rmap+0x13b/0x173
[  538.245852]  ice_free_cpu_rx_rmap.part.2+0x58/0xa0 [ice]
[  538.251208]  ice_remove_arfs+0xb2/0xf0 [ice]
[  538.255506]  ice_remove+0x4e7/0x620 [ice]
[  538.259553]  pci_device_remove+0xf3/0x290
[  538.275025]  device_release_driver_internal+0x204/0x4b0
[  538.280263]  driver_detach+0xf8/0x1ba
[  538.283937]  bus_remove_driver+0x117/0x2db
[  538.288047]  pci_unregister_driver+0x30/0x230
[  538.297650]  ice_module_exit+0xc/0x2b [ice]
[  538.301864]  __x64_sys_delete_module+0x2cc/0x4a0
[  538.320373]  do_syscall_64+0xa5/0x450
[  538.324046]  entry_SYSCALL_64_after_hwframe+0x6a/0xdf
[  538.329103] RIP: 0033:0x7f7a2498c05b
[  538.332686] Code: 73 01 c3 48 8b 0d 2d 4e 38 00 f7 d8 64 89 01 48 83 c8 ff c8
[  538.351437] RSP: 002b:00007ffed8b6f3e8 EFLAGS: 00000206 ORIG_RAX: 00000000000
[  538.359012] RAX: ffffffffffffffda RBX: 000055d81e2547a0 RCX: 00007f7a2498c05b
[  538.366145] RDX: 000000000000000a RSI: 0000000000000800 RDI: 000055d81e254808
[  538.373279] RBP: 0000000000000000 R08: 00007ffed8b6e361 R09: 0000000000000000
[  538.380411] R10: 00007f7a24ac3480 R11: 0000000000000206 R12: 00007ffed8b6f618
[  538.387544] R13: 00007ffed8b712ba R14: 000055d81e2542a0 R15: 000055d81e2547a0
[  538.394695]
[  538.396193] Allocated by task 469:
[  538.399599]  kasan_save_stack+0x19/0x40
[  538.403437]  __kasan_kmalloc+0x7d/0xa0
[  538.407192]  kmem_cache_alloc_trace+0x188/0x2b0
[  538.411732]  irq_cpu_rmap_add+0x4a/0x2e0
[  538.415659]  ice_set_cpu_rx_rmap+0x28a/0x490 [ice]
[  538.420476]  ice_probe+0x1f9c/0x43d0 [ice]
[  538.424594]  local_pci_probe+0xd8/0x170
[  538.428433]  work_for_cpu_fn+0x51/0xa0
[  538.432186]  process_one_work+0x919/0x17d0
[  538.436284]  worker_thread+0x541/0xb40
[  538.440038]  kthread+0x30d/0x3c0
[  538.443269]  ret_from_fork+0x24/0x50
[  538.446850]
[  538.448350] Freed by task 16217:
[  538.451582]  kasan_save_stack+0x19/0x40
[  538.455420]  kasan_set_track+0x1c/0x30
[  538.459172]  kasan_set_free_info+0x20/0x30
[  538.463272]  __kasan_slab_free+0xdf/0x110
[  538.467284]  slab_free_freelist_hook+0xc6/0x190
[  538.471818]  kfree+0xd9/0x2b0
[  538.474791]  irq_set_affinity_notifier+0x246/0x2c0
[  538.479583]  ice_vsi_free_irq+0x719/0xad0 [ice]
[  538.484142]  ice_vsi_close+0x28/0x50 [ice]
[  538.488258]  ice_stop+0x66/0x90 [ice]
[  538.491942]  __dev_close_many+0x19c/0x2c0
[  538.495956]  __dev_change_flags+0x1fd/0x580
[  538.500142]  dev_change_flags+0x7c/0x150
[  538.504068]  do_setlink+0x97d/0x2e70
[  538.507646]  __rtnl_newlink+0x9b7/0x1210
[  538.511573]  rtnl_newlink+0x61/0x90
[  538.515064]  rtnetlink_rcv_msg+0x34e/0x8d0
[  538.519164]  netlink_rcv_skb+0x123/0x390
[  538.523090]  netlink_unicast+0x40f/0x5d0
[  538.527016]  netlink_sendmsg+0x73d/0xb60
[  538.530944]  sock_sendmsg+0xde/0x110
[  538.534531]  ____sys_sendmsg+0x593/0x840
[  538.538458]  ___sys_sendmsg+0xe9/0x160
[  538.542210]  __sys_sendmsg+0xd3/0x170
[  538.545876]  do_syscall_64+0xa5/0x450
[  538.549542]  entry_SYSCALL_64_after_hwframe+0x6a/0xdf
[  538.554594]
[  538.556093] The buggy address belongs to the object at ff110022d1f9e300
[  538.556093]  which belongs to the cache kmalloc-192 of size 192
[  538.568601] The buggy address is located 0 bytes inside of
[  538.568601]  192-byte region [ff110022d1f9e300, ff110022d1f9e3c0)
[  538.580152] The buggy address belongs to the page:
[  538.584946] page:ffd400008b47e780 refcount:1 mapcount:0 mapping:0000000000000
[  538.597538] flags: 0x57ffffc0008100(slab|head|node=1|zone=2|lastcpupid=0x1ff)
[  538.604931] raw: 0057ffffc0008100 dead000000000100 dead000000000200 ff1100010
[  538.612670] raw: 0000000000000000 0000000000200020 00000001ffffffff 000000000
[  538.620408] page dumped because: kasan: bad access detected
[  538.625983]
[  538.627480] Memory state around the buggy address:
[  538.632276]  ff110022d1f9e200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0
[  538.639493]  ff110022d1f9e280: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc c
[  538.646712] >ff110022d1f9e300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb b
[  538.653931]                    ^
[  538.657164]  ff110022d1f9e380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc c
[  538.664386]  ff110022d1f9e400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0
[  538.671603] =================================================================

Fixes: 28bf26724fdb ("ice: Implement aRFS")
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
 drivers/net/ethernet/intel/ice/ice_lib.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Alexander Lobakin April 4, 2022, 11:04 a.m. UTC | #1
From: Ivan Vecera <ivecera@redhat.com>
Date: Mon,  4 Apr 2022 12:06:14 +0200

> When CONFIG_RFS_ACCEL is enabled the driver uses CPU affinity
> reverse-maps that set CPU affinity notifier in the background.
> 
> If the interface is put down then ice_vsi_free_irq() is called
> via ice_vsi_close() and this clears affinity notifiers of IRQs
> associated with the VSI and old notifier's release callback
> is called - for this case this is cpu_rmap_release() that
> frees allocated cpu_rmap.
> 
> During device removal (ice_remove()) free_irq_cpu_rmap() is called
> and it tries to free already de-allocated cpu_rmap.
> 
> Do not clear IRQ affinity notifier in ice_vsi_free_irq() when
> CONFIG_RFS_ACCEL is enabled. This is a code-path that
> commit 28bf26724fdb ("ice: Implement aRFS") forgot to handle.

Hey, thanks for the fix!
I posted a patch which supercedes these changes to the internal
review on Friday. I would proceed with applying mine (which I'll
submit in 2 hours, it should've waited for the internal acks first),
but for sure I can add you as 'Co-Developed-by:' if you want (or
vice versa, me as co-dev-by?).

> 
> Reproducer:
> [root@host ~]# ip link set ens7f0 up
> [root@host ~]# ip link set ens7f0 down

--- 8< ---

>  		/* clear the affinity_mask in the IRQ descriptor */
>  		irq_set_affinity_hint(irq_num, NULL);
> -- 
> 2.35.1

Thanks,
Al
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 6d6233204388..34bc7710a6b5 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -2701,7 +2701,8 @@  void ice_vsi_free_irq(struct ice_vsi *vsi)
 			continue;
 
 		/* clear the affinity notifier in the IRQ descriptor */
-		irq_set_affinity_notifier(irq_num, NULL);
+		if (!IS_ENABLED(CONFIG_RFS_ACCEL))
+			irq_set_affinity_notifier(irq_num, NULL);
 
 		/* clear the affinity_mask in the IRQ descriptor */
 		irq_set_affinity_hint(irq_num, NULL);