Skip to content

Commit 2dbb5e9

Browse files
John Sperbeckgregkh
authored andcommitted
net: netpoll: ensure skb_pool list is always initialized
commit f0d0277 upstream. When __netpoll_setup() is called directly, instead of through netpoll_setup(), the np->skb_pool list head isn't initialized. If skb_pool_flush() is later called, then we hit a NULL pointer in skb_queue_purge_reason(). This can be seen with this repro, when CONFIG_NETCONSOLE is enabled as a module: ip tuntap add mode tap tap0 ip link add name br0 type bridge ip link set dev tap0 master br0 modprobe netconsole [email protected]/br0,[email protected]/ rmmod netconsole The backtrace is: BUG: kernel NULL pointer dereference, address: 0000000000000008 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page ... ... ... Call Trace: <TASK> __netpoll_free+0xa5/0xf0 br_netpoll_cleanup+0x43/0x50 [bridge] do_netpoll_cleanup+0x43/0xc0 netconsole_netdev_event+0x1e3/0x300 [netconsole] unregister_netdevice_notifier+0xd9/0x150 cleanup_module+0x45/0x920 [netconsole] __se_sys_delete_module+0x205/0x290 do_syscall_64+0x70/0x150 entry_SYSCALL_64_after_hwframe+0x76/0x7e Move the skb_pool list setup and initial skb fill into __netpoll_setup(). Fixes: 221a9c1 ("net: netpoll: Individualize the skb pool") Signed-off-by: John Sperbeck <[email protected]> Reviewed-by: Breno Leitao <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c45a1db commit 2dbb5e9

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

net/core/netpoll.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
632632
const struct net_device_ops *ops;
633633
int err;
634634

635+
skb_queue_head_init(&np->skb_pool);
636+
635637
if (ndev->priv_flags & IFF_DISABLE_NETPOLL) {
636638
np_err(np, "%s doesn't support polling, aborting\n",
637639
ndev->name);
@@ -667,6 +669,9 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
667669
strscpy(np->dev_name, ndev->name, IFNAMSIZ);
668670
npinfo->netpoll = np;
669671

672+
/* fill up the skb queue */
673+
refill_skbs(np);
674+
670675
/* last thing to do is link it to the net device structure */
671676
rcu_assign_pointer(ndev->npinfo, npinfo);
672677

@@ -686,8 +691,6 @@ int netpoll_setup(struct netpoll *np)
686691
struct in_device *in_dev;
687692
int err;
688693

689-
skb_queue_head_init(&np->skb_pool);
690-
691694
rtnl_lock();
692695
if (np->dev_name[0]) {
693696
struct net *net = current->nsproxy->net_ns;
@@ -787,9 +790,6 @@ int netpoll_setup(struct netpoll *np)
787790
}
788791
}
789792

790-
/* fill up the skb queue */
791-
refill_skbs(np);
792-
793793
err = __netpoll_setup(np, ndev);
794794
if (err)
795795
goto flush;

0 commit comments

Comments
 (0)