From: Sasha Levin Date: Thu, 5 Sep 2019 08:38:51 +0000 (-0400) Subject: fixes for 5.2 X-Git-Tag: v4.4.191~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cf6859de3de6f4900d5c67d8662fd28c668319d8;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.2 Signed-off-by: Sasha Levin --- diff --git a/queue-5.2/hsr-fix-a-null-pointer-deref-in-hsr_dev_xmit.patch b/queue-5.2/hsr-fix-a-null-pointer-deref-in-hsr_dev_xmit.patch new file mode 100644 index 00000000000..07e7d636cd3 --- /dev/null +++ b/queue-5.2/hsr-fix-a-null-pointer-deref-in-hsr_dev_xmit.patch @@ -0,0 +1,86 @@ +From ca9e700326e2a1498f5c2fcfe1e4a8b4155eeb02 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Wed, 3 Jul 2019 17:21:14 -0700 +Subject: hsr: fix a NULL pointer deref in hsr_dev_xmit() + +[ Upstream commit edf070a0fb45ac845f534baf172fbadbeb5048c6 ] + +hsr_port_get_hsr() could return NULL and kernel +could crash: + + BUG: kernel NULL pointer dereference, address: 0000000000000010 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 8000000074b84067 P4D 8000000074b84067 PUD 7057d067 PMD 0 + Oops: 0000 [#1] SMP PTI + CPU: 0 PID: 754 Comm: a.out Not tainted 5.2.0-rc6+ #718 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014 + RIP: 0010:hsr_dev_xmit+0x20/0x31 + Code: 48 8b 1b eb e0 5b 5d 41 5c c3 66 66 66 66 90 55 48 89 fd 48 8d be 40 0b 00 00 be 04 00 00 00 e8 ee f2 ff ff 48 89 ef 48 89 c6 <48> 8b 40 10 48 89 45 10 e8 6c 1b 00 00 31 c0 5d c3 66 66 66 66 90 + RSP: 0018:ffffb5b400003c48 EFLAGS: 00010246 + RAX: 0000000000000000 RBX: ffff9821b4509a88 RCX: 0000000000000000 + RDX: ffff9821b4509a88 RSI: 0000000000000000 RDI: ffff9821bc3fc7c0 + RBP: ffff9821bc3fc7c0 R08: 0000000000000000 R09: 00000000000c2019 + R10: 0000000000000000 R11: 0000000000000002 R12: ffff9821bc3fc7c0 + R13: ffff9821b4509a88 R14: 0000000000000000 R15: 000000000000006e + FS: 00007fee112a1800(0000) GS:ffff9821bd800000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000010 CR3: 000000006e9ce000 CR4: 00000000000406f0 + Call Trace: + + netdev_start_xmit+0x1b/0x38 + dev_hard_start_xmit+0x121/0x21e + ? validate_xmit_skb.isra.0+0x19/0x1e3 + __dev_queue_xmit+0x74c/0x823 + ? lockdep_hardirqs_on+0x12b/0x17d + ip6_finish_output2+0x3d3/0x42c + ? ip6_mtu+0x55/0x5c + ? mld_sendpack+0x191/0x229 + mld_sendpack+0x191/0x229 + mld_ifc_timer_expire+0x1f7/0x230 + ? mld_dad_timer_expire+0x58/0x58 + call_timer_fn+0x12e/0x273 + __run_timers.part.0+0x174/0x1b5 + ? mld_dad_timer_expire+0x58/0x58 + ? sched_clock_cpu+0x10/0xad + ? mark_lock+0x26/0x1f2 + ? __lock_is_held+0x40/0x71 + run_timer_softirq+0x26/0x48 + __do_softirq+0x1af/0x392 + irq_exit+0x53/0xa2 + smp_apic_timer_interrupt+0x1c4/0x1d9 + apic_timer_interrupt+0xf/0x20 + + +Cc: Arvid Brodin +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/hsr/hsr_device.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index e6e3a7a1e3d4c..05ac0eaa72c4e 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -227,9 +227,13 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) + struct hsr_port *master; + + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); +- skb->dev = master->dev; +- hsr_forward_skb(skb, master); +- ++ if (master) { ++ skb->dev = master->dev; ++ hsr_forward_skb(skb, master); ++ } else { ++ atomic_long_inc(&dev->tx_dropped); ++ dev_kfree_skb_any(skb); ++ } + return NETDEV_TX_OK; + } + +-- +2.20.1 + diff --git a/queue-5.2/hsr-switch-dellink-to-ndo_uninit.patch b/queue-5.2/hsr-switch-dellink-to-ndo_uninit.patch new file mode 100644 index 00000000000..0f36f5d48a9 --- /dev/null +++ b/queue-5.2/hsr-switch-dellink-to-ndo_uninit.patch @@ -0,0 +1,119 @@ +From 7c46418f8ce18ac0d6ec787ee0e398119d615228 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Tue, 9 Jul 2019 23:24:54 -0700 +Subject: hsr: switch ->dellink() to ->ndo_uninit() + +[ Upstream commit 311633b604063a8a5d3fbc74d0565b42df721f68 ] + +Switching from ->priv_destructor to dellink() has an unexpected +consequence: existing RCU readers, that is, hsr_port_get_hsr() +callers, may still be able to read the port list. + +Instead of checking the return value of each hsr_port_get_hsr(), +we can just move it to ->ndo_uninit() which is called after +device unregister and synchronize_net(), and we still have RTNL +lock there. + +Fixes: b9a1e627405d ("hsr: implement dellink to clean up resources") +Fixes: edf070a0fb45 ("hsr: fix a NULL pointer deref in hsr_dev_xmit()") +Reported-by: syzbot+097ef84cdc95843fbaa8@syzkaller.appspotmail.com +Cc: Arvid Brodin +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/hsr/hsr_device.c | 18 ++++++++---------- + net/hsr/hsr_device.h | 1 - + net/hsr/hsr_netlink.c | 7 ------- + 3 files changed, 8 insertions(+), 18 deletions(-) + +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index 05ac0eaa72c4e..08c02dbb3d695 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -227,13 +227,8 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) + struct hsr_port *master; + + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); +- if (master) { +- skb->dev = master->dev; +- hsr_forward_skb(skb, master); +- } else { +- atomic_long_inc(&dev->tx_dropped); +- dev_kfree_skb_any(skb); +- } ++ skb->dev = master->dev; ++ hsr_forward_skb(skb, master); + return NETDEV_TX_OK; + } + +@@ -348,7 +343,11 @@ static void hsr_announce(struct timer_list *t) + rcu_read_unlock(); + } + +-void hsr_dev_destroy(struct net_device *hsr_dev) ++/* This has to be called after all the readers are gone. ++ * Otherwise we would have to check the return value of ++ * hsr_port_get_hsr(). ++ */ ++static void hsr_dev_destroy(struct net_device *hsr_dev) + { + struct hsr_priv *hsr; + struct hsr_port *port; +@@ -363,8 +362,6 @@ void hsr_dev_destroy(struct net_device *hsr_dev) + del_timer_sync(&hsr->prune_timer); + del_timer_sync(&hsr->announce_timer); + +- synchronize_rcu(); +- + hsr_del_self_node(&hsr->self_node_db); + hsr_del_nodes(&hsr->node_db); + } +@@ -375,6 +372,7 @@ static const struct net_device_ops hsr_device_ops = { + .ndo_stop = hsr_dev_close, + .ndo_start_xmit = hsr_dev_xmit, + .ndo_fix_features = hsr_fix_features, ++ .ndo_uninit = hsr_dev_destroy, + }; + + static struct device_type hsr_type = { +diff --git a/net/hsr/hsr_device.h b/net/hsr/hsr_device.h +index d0fa6b0696d25..6d7759c4f5f98 100644 +--- a/net/hsr/hsr_device.h ++++ b/net/hsr/hsr_device.h +@@ -14,7 +14,6 @@ + void hsr_dev_setup(struct net_device *dev); + int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], + unsigned char multicast_spec, u8 protocol_version); +-void hsr_dev_destroy(struct net_device *hsr_dev); + void hsr_check_carrier_and_operstate(struct hsr_priv *hsr); + bool is_hsr_master(struct net_device *dev); + int hsr_get_max_mtu(struct hsr_priv *hsr); +diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c +index 160edd24de4e2..8f8337f893bad 100644 +--- a/net/hsr/hsr_netlink.c ++++ b/net/hsr/hsr_netlink.c +@@ -69,12 +69,6 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev, + return hsr_dev_finalize(dev, link, multicast_spec, hsr_version); + } + +-static void hsr_dellink(struct net_device *hsr_dev, struct list_head *head) +-{ +- hsr_dev_destroy(hsr_dev); +- unregister_netdevice_queue(hsr_dev, head); +-} +- + static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev) + { + struct hsr_priv *hsr; +@@ -119,7 +113,6 @@ static struct rtnl_link_ops hsr_link_ops __read_mostly = { + .priv_size = sizeof(struct hsr_priv), + .setup = hsr_dev_setup, + .newlink = hsr_newlink, +- .dellink = hsr_dellink, + .fill_info = hsr_fill_info, + }; + +-- +2.20.1 + diff --git a/queue-5.2/series b/queue-5.2/series index 5b3c6322517..84dd483a808 100644 --- a/queue-5.2/series +++ b/queue-5.2/series @@ -141,3 +141,5 @@ drm-i915-dp-fix-dsc-enable-code-to-use-cpu_transcode.patch x86-ptrace-fix-up-botched-merge-of-spectrev1-fix.patch bpf-fix-use-after-free-in-prog-symbol-exposure.patch hsr-implement-dellink-to-clean-up-resources.patch +hsr-fix-a-null-pointer-deref-in-hsr_dev_xmit.patch +hsr-switch-dellink-to-ndo_uninit.patch