summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorJosh Elsasser <jelsasser@appneta.com>2019-07-01 16:41:43 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-10 09:55:42 +0200
commitd76e874053c31555af4fa0ec9819978527ba84e6 (patch)
tree9156ff39b0c53a7b38f369d2b3e87ab968e84e41 /net/core
parent4451dc92e5bbd31363dac5c82fc35080b330933b (diff)
net: check before dereferencing netdev_ops during busy poll
init_dummy_netdev() leaves its netdev_ops pointer zeroed. This leads to a NULL pointer dereference when sk_busy_loop fires against an iwlwifi wireless adapter and checks napi->dev->netdev_ops->ndo_busy_poll. Avoid this by ensuring napi->dev->netdev_ops is valid before following the pointer, avoiding the following panic when busy polling on a dummy netdev: BUG: unable to handle kernel NULL pointer dereference at 00000000000000c8 IP: [<ffffffff817b4b72>] sk_busy_loop+0x92/0x2f0 Call Trace: [<ffffffff815a3134>] ? uart_write_room+0x74/0xf0 [<ffffffff817964a9>] sock_poll+0x99/0xa0 [<ffffffff81223142>] do_sys_poll+0x2e2/0x520 [<ffffffff8118d3fc>] ? get_page_from_freelist+0x3bc/0xa30 [<ffffffff810ada22>] ? update_curr+0x62/0x140 [<ffffffff811ea671>] ? __slab_free+0xa1/0x2a0 [<ffffffff811ea671>] ? __slab_free+0xa1/0x2a0 [<ffffffff8179dbb1>] ? skb_free_head+0x21/0x30 [<ffffffff81221bd0>] ? poll_initwait+0x50/0x50 [<ffffffff811eaa36>] ? kmem_cache_free+0x1c6/0x1e0 [<ffffffff815a4884>] ? uart_write+0x124/0x1d0 [<ffffffff810bd1cd>] ? remove_wait_queue+0x4d/0x60 [<ffffffff810bd224>] ? __wake_up+0x44/0x50 [<ffffffff81582731>] ? tty_write_unlock+0x31/0x40 [<ffffffff8158c5c6>] ? tty_ldisc_deref+0x16/0x20 [<ffffffff81584820>] ? tty_write+0x1e0/0x2f0 [<ffffffff81587e50>] ? process_echoes+0x80/0x80 [<ffffffff8120c17b>] ? __vfs_write+0x2b/0x130 [<ffffffff8120d09a>] ? vfs_write+0x15a/0x1a0 [<ffffffff81223455>] SyS_poll+0x75/0x100 [<ffffffff819a6524>] entry_SYSCALL_64_fastpath+0x24/0xcf Commit 79e7fff47b7b ("net: remove support for per driver ndo_busy_poll()") indirectly fixed this upstream in linux-4.11 by removing the offending pointer usage. No other users of napi->dev touch its netdev_ops. Fixes: ce6aea93f751 ("net: network drivers no longer need to implement ndo_busy_poll()") # 4.9.y Signed-off-by: Josh Elsasser <jelsasser@appneta.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Tested-by: Matteo Croce <mcroce@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 4e10bae5e3da..f693afe608d7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5083,7 +5083,10 @@ bool sk_busy_loop(struct sock *sk, int nonblock)
goto out;
/* Note: ndo_busy_poll method is optional in linux-4.5 */
- busy_poll = napi->dev->netdev_ops->ndo_busy_poll;
+ if (napi->dev->netdev_ops)
+ busy_poll = napi->dev->netdev_ops->ndo_busy_poll;
+ else
+ busy_poll = NULL;
do {
rc = 0;