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 ---
No changes since V2[1], resent as per discussiond on -stable[2]. I hope this is the correct way to send net fixes for older LTS releases, I'm going off of the latest netdev FAQ:
For earlier stable releases, each stable branch maintainer is supposed to take care of them. If you find any patch is missing from an earlier stable branch, please notify stable@vger.kernel.org with either a commit ID or a formal patch backported, and CC Dave and other relevant networking developers.
[1]: https://patchwork.ozlabs.org/patch/884986/ [2]: https://lore.kernel.org/stable/CAGnkfhx3ykbEsW+=FtpMFWU=_Vnie7RpPYWpWqa1S1HP...
net/core/dev.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
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;
From: Josh Elsasser jelsasser@appneta.com Date: Mon, 1 Jul 2019 16:41:43 -0700
No changes since V2[1], resent as per discussiond on -stable[2]. I hope this is the correct way to send net fixes for older LTS releases, I'm going off of the latest netdev FAQ:
I just tried to apply this with "git am" to the current v4.19 -stable branch and it failed.
[davem@localhost linux-stable]$ git am --signoff diff Applying: net: check before dereferencing netdev_ops during busy poll error: patch failed: net/core/dev.c:5083 error: net/core/dev.c: patch does not apply Patch failed at 0001 net: check before dereferencing netdev_ops during busy poll hint: Use 'git am --show-current-patch' to see the failed patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort".
On Jul 1, 2019, at 6:51 PM, David Miller davem@davemloft.net wrote:
I just tried to apply this with "git am" to the current v4.19 -stable branch and it failed.
This is only needed for the v4.9 stable kernel, ndo_busy_poll (and this NPE) went away in kernel 4.11.
Sorry, I probably should have called that out more explicitly.
linux-stable-mirror@lists.linaro.org