In the Linux kernel, the following vulnerability has been resolved:
net: hns3: put off calling register_netdev() until client initialize complete
Currently, the netdevice is registered before client initializing complete. So there is a timewindow between netdevice available and usable. In this case, if user try to change the channel number or ring param, it may cause the hns3setrxcpurmap() being called twice, and report bug.
[47199.416502] hns3 0000:35:00.0 eth1: set channels: tqpnum=1, rxfh=0 [47199.430340] hns3 0000:35:00.0 eth1: already uninitialized [47199.438554] hns3 0000:35:00.0: rss changes from 4 to 1 [47199.511854] hns3 0000:35:00.0: Channels changed, rsssize from 4 to 1, tqps from 4 to 1 [47200.163524] ------------[ cut here ]------------ [47200.171674] kernel BUG at lib/cpurmap.c:142! [47200.177847] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP [47200.185259] Modules linked in: hclge(+) hns3(-) hns3cae(O) hnsrocehwv2 hnae3 vfioiommutype1 vfiopci vfiovirqfd vfio pv680mii(O) [last unloaded: hclge] [47200.205912] CPU: 1 PID: 8260 Comm: ethtool Tainted: G O 5.11.0-rc3+ #1 [47200.215601] Hardware name: , xxxxxx 02/04/2021 [47200.223052] pstate: 60400009 (nZCv daif +PAN -UAO -TCO BTYPE=--) [47200.230188] pc : cpurmapadd+0x38/0x40 [47200.237472] lr : irqcpurmapadd+0x84/0x140 [47200.243291] sp : ffff800010e93a30 [47200.247295] x29: ffff800010e93a30 x28: ffff082100584880 [47200.254155] x27: 0000000000000000 x26: 0000000000000000 [47200.260712] x25: 0000000000000000 x24: 0000000000000004 [47200.267241] x23: ffff08209ba03000 x22: ffff08209ba038c0 [47200.273789] x21: 000000000000003f x20: ffff0820e2bc1680 [47200.280400] x19: ffff0820c970ec80 x18: 00000000000000c0 [47200.286944] x17: 0000000000000000 x16: ffffb43debe4a0d0 [47200.293456] x15: fffffc2082990600 x14: dead000000000122 [47200.300059] x13: ffffffffffffffff x12: 000000000000003e [47200.306606] x11: ffff0820815b8080 x10: ffff53e411988000 [47200.313171] x9 : 0000000000000000 x8 : ffff0820e2bc1700 [47200.319682] x7 : 0000000000000000 x6 : 000000000000003f [47200.326170] x5 : 0000000000000040 x4 : ffff800010e93a20 [47200.332656] x3 : 0000000000000004 x2 : ffff0820c970ec80 [47200.339168] x1 : ffff0820e2bc1680 x0 : 0000000000000004 [47200.346058] Call trace: [47200.349324] cpurmapadd+0x38/0x40 [47200.354300] hns3setrxcpurmap+0x6c/0xe0 [hns3] [47200.362294] hns3resetnotifyinitenet+0x1cc/0x340 [hns3] [47200.370049] hns3changechannels+0x40/0xb0 [hns3] [47200.376770] hns3setchannels+0x12c/0x2a0 [hns3] [47200.383353] ethtoolsetchannels+0x140/0x250 [47200.389772] devethtool+0x714/0x23d0 [47200.394440] devioctl+0x4cc/0x640 [47200.399277] sockdoioctl+0x100/0x2a0 [47200.404574] sockioctl+0x28c/0x470 [47200.409079] _arm64sysioctl+0xb4/0x100 [47200.415217] el0svccommon.constprop.0+0x84/0x210 [47200.422088] doel0svc+0x28/0x34 [47200.426387] el0svc+0x28/0x70 [47200.431308] el0synchandler+0x1a4/0x1b0 [47200.436477] el0_sync+0x174/0x180 [47200.441562] Code: 11000405 79000c45 f8247861 d65f03c0 (d4210000) [47200.448869] ---[ end trace a01efe4ce42e5f34 ]---
The process is like below: excuting hns3clientinit | registernetdev() | hns3setchannels() | | hns3setrxcpurmap() hns3resetnotifyuninitenet() | | | quit without calling function | hns3freerxcpurmap for flag | HNS3NICSTATEINITED is unset. | | | hns3resetnotifyinitenet() | | set HNS3NICSTATEINITED call hns3setrxcpu_rmap()-- crash
Fix it by calling registernetdev() at the end of function hns3client_init().