From 5efcf371cc1ef08d1b44bfd6b0fe6486b6e666b9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 2 Nov 2018 10:28:05 +0100 Subject: [PATCH] 4.9-stable patches added patches: bonding-fix-length-of-actor-system.patch ethtool-fix-a-privilege-escalation-bug.patch ip6_tunnel-fix-encapsulation-layout.patch ipv6-mcast-fix-a-use-after-free-in-inet6_mc_check.patch ipv6-ndisc-preserve-ipv6-control-buffer-if-protocol-error-handlers-are-called.patch llc-set-sock_rcu_free-in-llc_sap_add_socket.patch net-drop-skb-on-failure-in-ip_check_defrag.patch net-fix-pskb_trim_rcsum_slow-with-odd-trim-offset.patch net-ipv6-fix-index-counter-for-unicast-addresses-in-in6_dump_addrs.patch net-sched-gred-pass-the-right-attribute-to-gred_change_table_def.patch net-socket-fix-a-missing-check-bug.patch net-stmmac-fix-stmmac_mdio_reset-when-building-stmmac-as-modules.patch net-udp-fix-handling-of-checksum_complete-packets.patch r8169-fix-napi-handling-under-high-load.patch rtnetlink-disallow-fdb-configuration-for-non-ethernet-device.patch sctp-fix-race-on-sctp_id2asoc.patch vhost-fix-spectre-v1-vulnerability.patch --- .../bonding-fix-length-of-actor-system.patch | 34 ++++ ...htool-fix-a-privilege-escalation-bug.patch | 73 ++++++++ .../ip6_tunnel-fix-encapsulation-layout.patch | 70 +++++++ ...x-a-use-after-free-in-inet6_mc_check.patch | 173 ++++++++++++++++++ ...f-protocol-error-handlers-are-called.patch | 53 ++++++ ...-sock_rcu_free-in-llc_sap_add_socket.patch | 37 ++++ ...op-skb-on-failure-in-ip_check_defrag.patch | 55 ++++++ ...trim_rcsum_slow-with-odd-trim-offset.patch | 47 +++++ ...-unicast-addresses-in-in6_dump_addrs.patch | 50 +++++ ...t-attribute-to-gred_change_table_def.patch | 54 ++++++ .../net-socket-fix-a-missing-check-bug.patch | 56 ++++++ ...eset-when-building-stmmac-as-modules.patch | 43 +++++ ...andling-of-checksum_complete-packets.patch | 146 +++++++++++++++ ...69-fix-napi-handling-under-high-load.patch | 52 ++++++ ...onfiguration-for-non-ethernet-device.patch | 124 +++++++++++++ queue-4.9/sctp-fix-race-on-sctp_id2asoc.patch | 62 +++++++ queue-4.9/series | 17 ++ .../vhost-fix-spectre-v1-vulnerability.patch | 42 +++++ 18 files changed, 1188 insertions(+) create mode 100644 queue-4.9/bonding-fix-length-of-actor-system.patch create mode 100644 queue-4.9/ethtool-fix-a-privilege-escalation-bug.patch create mode 100644 queue-4.9/ip6_tunnel-fix-encapsulation-layout.patch create mode 100644 queue-4.9/ipv6-mcast-fix-a-use-after-free-in-inet6_mc_check.patch create mode 100644 queue-4.9/ipv6-ndisc-preserve-ipv6-control-buffer-if-protocol-error-handlers-are-called.patch create mode 100644 queue-4.9/llc-set-sock_rcu_free-in-llc_sap_add_socket.patch create mode 100644 queue-4.9/net-drop-skb-on-failure-in-ip_check_defrag.patch create mode 100644 queue-4.9/net-fix-pskb_trim_rcsum_slow-with-odd-trim-offset.patch create mode 100644 queue-4.9/net-ipv6-fix-index-counter-for-unicast-addresses-in-in6_dump_addrs.patch create mode 100644 queue-4.9/net-sched-gred-pass-the-right-attribute-to-gred_change_table_def.patch create mode 100644 queue-4.9/net-socket-fix-a-missing-check-bug.patch create mode 100644 queue-4.9/net-stmmac-fix-stmmac_mdio_reset-when-building-stmmac-as-modules.patch create mode 100644 queue-4.9/net-udp-fix-handling-of-checksum_complete-packets.patch create mode 100644 queue-4.9/r8169-fix-napi-handling-under-high-load.patch create mode 100644 queue-4.9/rtnetlink-disallow-fdb-configuration-for-non-ethernet-device.patch create mode 100644 queue-4.9/sctp-fix-race-on-sctp_id2asoc.patch create mode 100644 queue-4.9/vhost-fix-spectre-v1-vulnerability.patch diff --git a/queue-4.9/bonding-fix-length-of-actor-system.patch b/queue-4.9/bonding-fix-length-of-actor-system.patch new file mode 100644 index 00000000000..ecbe62227c8 --- /dev/null +++ b/queue-4.9/bonding-fix-length-of-actor-system.patch @@ -0,0 +1,34 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Tobias Jungel +Date: Sun, 28 Oct 2018 12:54:10 +0100 +Subject: bonding: fix length of actor system + +From: Tobias Jungel + +[ Upstream commit 414dd6fb9a1a1b59983aea7bf0f79f0085ecc5b8 ] + +The attribute IFLA_BOND_AD_ACTOR_SYSTEM is sent to user space having the +length of sizeof(bond->params.ad_actor_system) which is 8 byte. This +patch aligns the length to ETH_ALEN to have the same MAC address exposed +as using sysfs. + +Fixes: f87fda00b6ed2 ("bonding: prevent out of bound accesses") +Signed-off-by: Tobias Jungel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_netlink.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/bonding/bond_netlink.c ++++ b/drivers/net/bonding/bond_netlink.c +@@ -628,8 +628,7 @@ static int bond_fill_info(struct sk_buff + goto nla_put_failure; + + if (nla_put(skb, IFLA_BOND_AD_ACTOR_SYSTEM, +- sizeof(bond->params.ad_actor_system), +- &bond->params.ad_actor_system)) ++ ETH_ALEN, &bond->params.ad_actor_system)) + goto nla_put_failure; + } + if (!bond_3ad_get_active_agg_info(bond, &info)) { diff --git a/queue-4.9/ethtool-fix-a-privilege-escalation-bug.patch b/queue-4.9/ethtool-fix-a-privilege-escalation-bug.patch new file mode 100644 index 00000000000..41f66486846 --- /dev/null +++ b/queue-4.9/ethtool-fix-a-privilege-escalation-bug.patch @@ -0,0 +1,73 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Wenwen Wang +Date: Mon, 8 Oct 2018 10:49:35 -0500 +Subject: ethtool: fix a privilege escalation bug + +From: Wenwen Wang + +[ Upstream commit 58f5bbe331c566f49c9559568f982202a278aa78 ] + +In dev_ethtool(), the eth command 'ethcmd' is firstly copied from the +use-space buffer 'useraddr' and checked to see whether it is +ETHTOOL_PERQUEUE. If yes, the sub-command 'sub_cmd' is further copied from +the user space. Otherwise, 'sub_cmd' is the same as 'ethcmd'. Next, +according to 'sub_cmd', a permission check is enforced through the function +ns_capable(). For example, the permission check is required if 'sub_cmd' is +ETHTOOL_SCOALESCE, but it is not necessary if 'sub_cmd' is +ETHTOOL_GCOALESCE, as suggested in the comment "Allow some commands to be +done by anyone". The following execution invokes different handlers +according to 'ethcmd'. Specifically, if 'ethcmd' is ETHTOOL_PERQUEUE, +ethtool_set_per_queue() is called. In ethtool_set_per_queue(), the kernel +object 'per_queue_opt' is copied again from the user-space buffer +'useraddr' and 'per_queue_opt.sub_command' is used to determine which +operation should be performed. Given that the buffer 'useraddr' is in the +user space, a malicious user can race to change the sub-command between the +two copies. In particular, the attacker can supply ETHTOOL_PERQUEUE and +ETHTOOL_GCOALESCE to bypass the permission check in dev_ethtool(). Then +before ethtool_set_per_queue() is called, the attacker changes +ETHTOOL_GCOALESCE to ETHTOOL_SCOALESCE. In this way, the attacker can +bypass the permission check and execute ETHTOOL_SCOALESCE. + +This patch enforces a check in ethtool_set_per_queue() after the second +copy from 'useraddr'. If the sub-command is different from the one obtained +in the first copy in dev_ethtool(), an error code EINVAL will be returned. + +Fixes: f38d138a7da6 ("net/ethtool: support set coalesce per queue") +Signed-off-by: Wenwen Wang +Reviewed-by: Michal Kubecek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/ethtool.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -2397,13 +2397,17 @@ roll_back: + return ret; + } + +-static int ethtool_set_per_queue(struct net_device *dev, void __user *useraddr) ++static int ethtool_set_per_queue(struct net_device *dev, ++ void __user *useraddr, u32 sub_cmd) + { + struct ethtool_per_queue_op per_queue_opt; + + if (copy_from_user(&per_queue_opt, useraddr, sizeof(per_queue_opt))) + return -EFAULT; + ++ if (per_queue_opt.sub_command != sub_cmd) ++ return -EINVAL; ++ + switch (per_queue_opt.sub_command) { + case ETHTOOL_GCOALESCE: + return ethtool_get_per_queue_coalesce(dev, useraddr, &per_queue_opt); +@@ -2669,7 +2673,7 @@ int dev_ethtool(struct net *net, struct + rc = ethtool_get_phy_stats(dev, useraddr); + break; + case ETHTOOL_PERQUEUE: +- rc = ethtool_set_per_queue(dev, useraddr); ++ rc = ethtool_set_per_queue(dev, useraddr, sub_cmd); + break; + case ETHTOOL_GLINKSETTINGS: + rc = ethtool_get_link_ksettings(dev, useraddr); diff --git a/queue-4.9/ip6_tunnel-fix-encapsulation-layout.patch b/queue-4.9/ip6_tunnel-fix-encapsulation-layout.patch new file mode 100644 index 00000000000..1683bc29954 --- /dev/null +++ b/queue-4.9/ip6_tunnel-fix-encapsulation-layout.patch @@ -0,0 +1,70 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Stefano Brivio +Date: Thu, 18 Oct 2018 21:25:07 +0200 +Subject: ip6_tunnel: Fix encapsulation layout + +From: Stefano Brivio + +[ Upstream commit d4d576f5ab7edcb757bb33e6a5600666a0b1232d ] + +Commit 058214a4d1df ("ip6_tun: Add infrastructure for doing +encapsulation") added the ip6_tnl_encap() call in ip6_tnl_xmit(), before +the call to ipv6_push_frag_opts() to append the IPv6 Tunnel Encapsulation +Limit option (option 4, RFC 2473, par. 5.1) to the outer IPv6 header. + +As long as the option didn't actually end up in generated packets, this +wasn't an issue. Then commit 89a23c8b528b ("ip6_tunnel: Fix missing tunnel +encapsulation limit option") fixed sending of this option, and the +resulting layout, e.g. for FoU, is: + +.-------------------.------------.----------.-------------------.----- - - +| Outer IPv6 Header | UDP header | Option 4 | Inner IPv6 Header | Payload +'-------------------'------------'----------'-------------------'----- - - + +Needless to say, FoU and GUE (at least) won't work over IPv6. The option +is appended by default, and I couldn't find a way to disable it with the +current iproute2. + +Turn this into a more reasonable: + +.-------------------.----------.------------.-------------------.----- - - +| Outer IPv6 Header | Option 4 | UDP header | Inner IPv6 Header | Payload +'-------------------'----------'------------'-------------------'----- - - + +With this, and with 84dad55951b0 ("udp6: fix encap return code for +resubmitting"), FoU and GUE work again over IPv6. + +Fixes: 058214a4d1df ("ip6_tun: Add infrastructure for doing encapsulation") +Signed-off-by: Stefano Brivio +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_tunnel.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1185,11 +1185,6 @@ route_lookup: + } + skb_dst_set(skb, dst); + +- if (encap_limit >= 0) { +- init_tel_txopt(&opt, encap_limit); +- ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL); +- } +- + /* Calculate max headroom for all the headers and adjust + * needed_headroom if necessary. + */ +@@ -1202,6 +1197,11 @@ route_lookup: + if (err) + return err; + ++ if (encap_limit >= 0) { ++ init_tel_txopt(&opt, encap_limit); ++ ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL); ++ } ++ + skb_push(skb, sizeof(struct ipv6hdr)); + skb_reset_network_header(skb); + ipv6h = ipv6_hdr(skb); diff --git a/queue-4.9/ipv6-mcast-fix-a-use-after-free-in-inet6_mc_check.patch b/queue-4.9/ipv6-mcast-fix-a-use-after-free-in-inet6_mc_check.patch new file mode 100644 index 00000000000..c4d015b76d7 --- /dev/null +++ b/queue-4.9/ipv6-mcast-fix-a-use-after-free-in-inet6_mc_check.patch @@ -0,0 +1,173 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Eric Dumazet +Date: Fri, 12 Oct 2018 18:58:53 -0700 +Subject: ipv6: mcast: fix a use-after-free in inet6_mc_check + +From: Eric Dumazet + +[ Upstream commit dc012f3628eaecfb5ba68404a5c30ef501daf63d ] + +syzbot found a use-after-free in inet6_mc_check [1] + +The problem here is that inet6_mc_check() uses rcu +and read_lock(&iml->sflock) + +So the fact that ip6_mc_leave_src() is called under RTNL +and the socket lock does not help us, we need to acquire +iml->sflock in write mode. + +In the future, we should convert all this stuff to RCU. + +[1] +BUG: KASAN: use-after-free in ipv6_addr_equal include/net/ipv6.h:521 [inline] +BUG: KASAN: use-after-free in inet6_mc_check+0xae7/0xb40 net/ipv6/mcast.c:649 +Read of size 8 at addr ffff8801ce7f2510 by task syz-executor0/22432 + +CPU: 1 PID: 22432 Comm: syz-executor0 Not tainted 4.19.0-rc7+ #280 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x1c4/0x2b4 lib/dump_stack.c:113 + print_address_description.cold.8+0x9/0x1ff mm/kasan/report.c:256 + kasan_report_error mm/kasan/report.c:354 [inline] + kasan_report.cold.9+0x242/0x309 mm/kasan/report.c:412 + __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433 + ipv6_addr_equal include/net/ipv6.h:521 [inline] + inet6_mc_check+0xae7/0xb40 net/ipv6/mcast.c:649 + __raw_v6_lookup+0x320/0x3f0 net/ipv6/raw.c:98 + ipv6_raw_deliver net/ipv6/raw.c:183 [inline] + raw6_local_deliver+0x3d3/0xcb0 net/ipv6/raw.c:240 + ip6_input_finish+0x467/0x1aa0 net/ipv6/ip6_input.c:345 + NF_HOOK include/linux/netfilter.h:289 [inline] + ip6_input+0xe9/0x600 net/ipv6/ip6_input.c:426 + ip6_mc_input+0x48a/0xd20 net/ipv6/ip6_input.c:503 + dst_input include/net/dst.h:450 [inline] + ip6_rcv_finish+0x17a/0x330 net/ipv6/ip6_input.c:76 + NF_HOOK include/linux/netfilter.h:289 [inline] + ipv6_rcv+0x120/0x640 net/ipv6/ip6_input.c:271 + __netif_receive_skb_one_core+0x14d/0x200 net/core/dev.c:4913 + __netif_receive_skb+0x2c/0x1e0 net/core/dev.c:5023 + netif_receive_skb_internal+0x12c/0x620 net/core/dev.c:5126 + napi_frags_finish net/core/dev.c:5664 [inline] + napi_gro_frags+0x75a/0xc90 net/core/dev.c:5737 + tun_get_user+0x3189/0x4250 drivers/net/tun.c:1923 + tun_chr_write_iter+0xb9/0x154 drivers/net/tun.c:1968 + call_write_iter include/linux/fs.h:1808 [inline] + do_iter_readv_writev+0x8b0/0xa80 fs/read_write.c:680 + do_iter_write+0x185/0x5f0 fs/read_write.c:959 + vfs_writev+0x1f1/0x360 fs/read_write.c:1004 + do_writev+0x11a/0x310 fs/read_write.c:1039 + __do_sys_writev fs/read_write.c:1112 [inline] + __se_sys_writev fs/read_write.c:1109 [inline] + __x64_sys_writev+0x75/0xb0 fs/read_write.c:1109 + do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x457421 +Code: 75 14 b8 14 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 34 b5 fb ff c3 48 83 ec 08 e8 1a 2d 00 00 48 89 04 24 b8 14 00 00 00 0f 05 <48> 8b 3c 24 48 89 c2 e8 63 2d 00 00 48 89 d0 48 83 c4 08 48 3d 01 +RSP: 002b:00007f2d30ecaba0 EFLAGS: 00000293 ORIG_RAX: 0000000000000014 +RAX: ffffffffffffffda RBX: 000000000000003e RCX: 0000000000457421 +RDX: 0000000000000001 RSI: 00007f2d30ecabf0 RDI: 00000000000000f0 +RBP: 0000000020000500 R08: 00000000000000f0 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000293 R12: 00007f2d30ecb6d4 +R13: 00000000004c4890 R14: 00000000004d7b90 R15: 00000000ffffffff + +Allocated by task 22437: + save_stack+0x43/0xd0 mm/kasan/kasan.c:448 + set_track mm/kasan/kasan.c:460 [inline] + kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:553 + __do_kmalloc mm/slab.c:3718 [inline] + __kmalloc+0x14e/0x760 mm/slab.c:3727 + kmalloc include/linux/slab.h:518 [inline] + sock_kmalloc+0x15a/0x1f0 net/core/sock.c:1983 + ip6_mc_source+0x14dd/0x1960 net/ipv6/mcast.c:427 + do_ipv6_setsockopt.isra.9+0x3afb/0x45d0 net/ipv6/ipv6_sockglue.c:743 + ipv6_setsockopt+0xbd/0x170 net/ipv6/ipv6_sockglue.c:933 + rawv6_setsockopt+0x59/0x140 net/ipv6/raw.c:1069 + sock_common_setsockopt+0x9a/0xe0 net/core/sock.c:3038 + __sys_setsockopt+0x1ba/0x3c0 net/socket.c:1902 + __do_sys_setsockopt net/socket.c:1913 [inline] + __se_sys_setsockopt net/socket.c:1910 [inline] + __x64_sys_setsockopt+0xbe/0x150 net/socket.c:1910 + do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Freed by task 22430: + save_stack+0x43/0xd0 mm/kasan/kasan.c:448 + set_track mm/kasan/kasan.c:460 [inline] + __kasan_slab_free+0x102/0x150 mm/kasan/kasan.c:521 + kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528 + __cache_free mm/slab.c:3498 [inline] + kfree+0xcf/0x230 mm/slab.c:3813 + __sock_kfree_s net/core/sock.c:2004 [inline] + sock_kfree_s+0x29/0x60 net/core/sock.c:2010 + ip6_mc_leave_src+0x11a/0x1d0 net/ipv6/mcast.c:2448 + __ipv6_sock_mc_close+0x20b/0x4e0 net/ipv6/mcast.c:310 + ipv6_sock_mc_close+0x158/0x1d0 net/ipv6/mcast.c:328 + inet6_release+0x40/0x70 net/ipv6/af_inet6.c:452 + __sock_release+0xd7/0x250 net/socket.c:579 + sock_close+0x19/0x20 net/socket.c:1141 + __fput+0x385/0xa30 fs/file_table.c:278 + ____fput+0x15/0x20 fs/file_table.c:309 + task_work_run+0x1e8/0x2a0 kernel/task_work.c:113 + tracehook_notify_resume include/linux/tracehook.h:193 [inline] + exit_to_usermode_loop+0x318/0x380 arch/x86/entry/common.c:166 + prepare_exit_to_usermode arch/x86/entry/common.c:197 [inline] + syscall_return_slowpath arch/x86/entry/common.c:268 [inline] + do_syscall_64+0x6be/0x820 arch/x86/entry/common.c:293 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +The buggy address belongs to the object at ffff8801ce7f2500 + which belongs to the cache kmalloc-192 of size 192 +The buggy address is located 16 bytes inside of + 192-byte region [ffff8801ce7f2500, ffff8801ce7f25c0) +The buggy address belongs to the page: +page:ffffea000739fc80 count:1 mapcount:0 mapping:ffff8801da800040 index:0x0 +flags: 0x2fffc0000000100(slab) +raw: 02fffc0000000100 ffffea0006f6e548 ffffea000737b948 ffff8801da800040 +raw: 0000000000000000 ffff8801ce7f2000 0000000100000010 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff8801ce7f2400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff8801ce7f2480: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc +>ffff8801ce7f2500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff8801ce7f2580: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc + ffff8801ce7f2600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/mcast.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2413,17 +2413,17 @@ static int ip6_mc_leave_src(struct sock + { + int err; + +- /* callers have the socket lock and rtnl lock +- * so no other readers or writers of iml or its sflist +- */ ++ write_lock_bh(&iml->sflock); + if (!iml->sflist) { + /* any-source empty exclude case */ +- return ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0); ++ err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0); ++ } else { ++ err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode, ++ iml->sflist->sl_count, iml->sflist->sl_addr, 0); ++ sock_kfree_s(sk, iml->sflist, IP6_SFLSIZE(iml->sflist->sl_max)); ++ iml->sflist = NULL; + } +- err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode, +- iml->sflist->sl_count, iml->sflist->sl_addr, 0); +- sock_kfree_s(sk, iml->sflist, IP6_SFLSIZE(iml->sflist->sl_max)); +- iml->sflist = NULL; ++ write_unlock_bh(&iml->sflock); + return err; + } + diff --git a/queue-4.9/ipv6-ndisc-preserve-ipv6-control-buffer-if-protocol-error-handlers-are-called.patch b/queue-4.9/ipv6-ndisc-preserve-ipv6-control-buffer-if-protocol-error-handlers-are-called.patch new file mode 100644 index 00000000000..484321c833b --- /dev/null +++ b/queue-4.9/ipv6-ndisc-preserve-ipv6-control-buffer-if-protocol-error-handlers-are-called.patch @@ -0,0 +1,53 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Stefano Brivio +Date: Wed, 24 Oct 2018 14:37:21 +0200 +Subject: ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are called + +From: Stefano Brivio + +[ Upstream commit ee1abcf689353f36d9322231b4320926096bdee0 ] + +Commit a61bbcf28a8c ("[NET]: Store skb->timestamp as offset to a base +timestamp") introduces a neighbour control buffer and zeroes it out in +ndisc_rcv(), as ndisc_recv_ns() uses it. + +Commit f2776ff04722 ("[IPV6]: Fix address/interface handling in UDP and +DCCP, according to the scoping architecture.") introduces the usage of the +IPv6 control buffer in protocol error handlers (e.g. inet6_iif() in +present-day __udp6_lib_err()). + +Now, with commit b94f1c0904da ("ipv6: Use icmpv6_notify() to propagate +redirect, instead of rt6_redirect()."), we call protocol error handlers +from ndisc_redirect_rcv(), after the control buffer is already stolen and +some parts are already zeroed out. This implies that inet6_iif() on this +path will always return zero. + +This gives unexpected results on UDP socket lookup in __udp6_lib_err(), as +we might actually need to match sockets for a given interface. + +Instead of always claiming the control buffer in ndisc_rcv(), do that only +when needed. + +Fixes: b94f1c0904da ("ipv6: Use icmpv6_notify() to propagate redirect, instead of rt6_redirect().") +Signed-off-by: Stefano Brivio +Reviewed-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ndisc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -1692,10 +1692,9 @@ int ndisc_rcv(struct sk_buff *skb) + return 0; + } + +- memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb)); +- + switch (msg->icmph.icmp6_type) { + case NDISC_NEIGHBOUR_SOLICITATION: ++ memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb)); + ndisc_recv_ns(skb); + break; + diff --git a/queue-4.9/llc-set-sock_rcu_free-in-llc_sap_add_socket.patch b/queue-4.9/llc-set-sock_rcu_free-in-llc_sap_add_socket.patch new file mode 100644 index 00000000000..c70823baf97 --- /dev/null +++ b/queue-4.9/llc-set-sock_rcu_free-in-llc_sap_add_socket.patch @@ -0,0 +1,37 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Cong Wang +Date: Thu, 11 Oct 2018 11:15:13 -0700 +Subject: llc: set SOCK_RCU_FREE in llc_sap_add_socket() + +From: Cong Wang + +[ Upstream commit 5a8e7aea953bdb6d4da13aff6f1e7f9c62023499 ] + +WHen an llc sock is added into the sk_laddr_hash of an llc_sap, +it is not marked with SOCK_RCU_FREE. + +This causes that the sock could be freed while it is still being +read by __llc_lookup_established() with RCU read lock. sock is +refcounted, but with RCU read lock, nothing prevents the readers +getting a zero refcnt. + +Fix it by setting SOCK_RCU_FREE in llc_sap_add_socket(). + +Reported-by: syzbot+11e05f04c15e03be5254@syzkaller.appspotmail.com +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/llc/llc_conn.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/llc/llc_conn.c ++++ b/net/llc/llc_conn.c +@@ -734,6 +734,7 @@ void llc_sap_add_socket(struct llc_sap * + llc_sk(sk)->sap = sap; + + spin_lock_bh(&sap->sk_lock); ++ sock_set_flag(sk, SOCK_RCU_FREE); + sap->sk_count++; + sk_nulls_add_node_rcu(sk, laddr_hb); + hlist_add_head(&llc->dev_hash_node, dev_hb); diff --git a/queue-4.9/net-drop-skb-on-failure-in-ip_check_defrag.patch b/queue-4.9/net-drop-skb-on-failure-in-ip_check_defrag.patch new file mode 100644 index 00000000000..0f84fe296a8 --- /dev/null +++ b/queue-4.9/net-drop-skb-on-failure-in-ip_check_defrag.patch @@ -0,0 +1,55 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Cong Wang +Date: Thu, 1 Nov 2018 12:02:37 -0700 +Subject: net: drop skb on failure in ip_check_defrag() + +From: Cong Wang + +[ Upstream commit 7de414a9dd91426318df7b63da024b2b07e53df5 ] + +Most callers of pskb_trim_rcsum() simply drop the skb when +it fails, however, ip_check_defrag() still continues to pass +the skb up to stack. This is suspicious. + +In ip_check_defrag(), after we learn the skb is an IP fragment, +passing the skb to callers makes no sense, because callers expect +fragments are defrag'ed on success. So, dropping the skb when we +can't defrag it is reasonable. + +Note, prior to commit 88078d98d1bb, this is not a big problem as +checksum will be fixed up anyway. After it, the checksum is not +correct on failure. + +Found this during code review. + +Fixes: 88078d98d1bb ("net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends") +Cc: Eric Dumazet +Signed-off-by: Cong Wang +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_fragment.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/net/ipv4/ip_fragment.c ++++ b/net/ipv4/ip_fragment.c +@@ -718,10 +718,14 @@ struct sk_buff *ip_check_defrag(struct n + if (ip_is_fragment(&iph)) { + skb = skb_share_check(skb, GFP_ATOMIC); + if (skb) { +- if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) +- return skb; +- if (pskb_trim_rcsum(skb, netoff + len)) +- return skb; ++ if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) { ++ kfree_skb(skb); ++ return NULL; ++ } ++ if (pskb_trim_rcsum(skb, netoff + len)) { ++ kfree_skb(skb); ++ return NULL; ++ } + memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); + if (ip_defrag(net, skb, user)) + return NULL; diff --git a/queue-4.9/net-fix-pskb_trim_rcsum_slow-with-odd-trim-offset.patch b/queue-4.9/net-fix-pskb_trim_rcsum_slow-with-odd-trim-offset.patch new file mode 100644 index 00000000000..418cf295e04 --- /dev/null +++ b/queue-4.9/net-fix-pskb_trim_rcsum_slow-with-odd-trim-offset.patch @@ -0,0 +1,47 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Dimitris Michailidis +Date: Fri, 19 Oct 2018 17:07:13 -0700 +Subject: net: fix pskb_trim_rcsum_slow() with odd trim offset + +From: Dimitris Michailidis + +[ Upstream commit d55bef5059dd057bd077155375c581b49d25be7e ] + +We've been getting checksum errors involving small UDP packets, usually +59B packets with 1 extra non-zero padding byte. netdev_rx_csum_fault() +has been complaining that HW is providing bad checksums. Turns out the +problem is in pskb_trim_rcsum_slow(), introduced in commit 88078d98d1bb +("net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends"). + +The source of the problem is that when the bytes we are trimming start +at an odd address, as in the case of the 1 padding byte above, +skb_checksum() returns a byte-swapped value. We cannot just combine this +with skb->csum using csum_sub(). We need to use csum_block_sub() here +that takes into account the parity of the start address and handles the +swapping. + +Matches existing code in __skb_postpull_rcsum() and esp_remove_trailer(). + +Fixes: 88078d98d1bb ("net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends") +Signed-off-by: Dimitris Michailidis +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1585,8 +1585,9 @@ int pskb_trim_rcsum_slow(struct sk_buff + if (skb->ip_summed == CHECKSUM_COMPLETE) { + int delta = skb->len - len; + +- skb->csum = csum_sub(skb->csum, +- skb_checksum(skb, len, delta, 0)); ++ skb->csum = csum_block_sub(skb->csum, ++ skb_checksum(skb, len, delta, 0), ++ len); + } + return __pskb_trim(skb, len); + } diff --git a/queue-4.9/net-ipv6-fix-index-counter-for-unicast-addresses-in-in6_dump_addrs.patch b/queue-4.9/net-ipv6-fix-index-counter-for-unicast-addresses-in-in6_dump_addrs.patch new file mode 100644 index 00000000000..45461f9dfd8 --- /dev/null +++ b/queue-4.9/net-ipv6-fix-index-counter-for-unicast-addresses-in-in6_dump_addrs.patch @@ -0,0 +1,50 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: David Ahern +Date: Fri, 19 Oct 2018 10:00:19 -0700 +Subject: net/ipv6: Fix index counter for unicast addresses in in6_dump_addrs + +From: David Ahern + +[ Upstream commit 4ba4c566ba8448a05e6257e0b98a21f1a0d55315 ] + +The loop wants to skip previously dumped addresses, so loops until +current index >= saved index. If the message fills it wants to save +the index for the next address to dump - ie., the one that did not +fit in the current message. + +Currently, it is incrementing the index counter before comparing to the +saved index, and then the saved index is off by 1 - it assumes the +current address is going to fit in the message. + +Change the index handling to increment only after a succesful dump. + +Fixes: 502a2ffd7376a ("ipv6: convert idev_list to list macros") +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -4721,8 +4721,8 @@ static int in6_dump_addrs(struct inet6_d + + /* unicast address incl. temp addr */ + list_for_each_entry(ifa, &idev->addr_list, if_list) { +- if (++ip_idx < s_ip_idx) +- continue; ++ if (ip_idx < s_ip_idx) ++ goto next; + err = inet6_fill_ifaddr(skb, ifa, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, +@@ -4731,6 +4731,8 @@ static int in6_dump_addrs(struct inet6_d + if (err < 0) + break; + nl_dump_check_consistent(cb, nlmsg_hdr(skb)); ++next: ++ ip_idx++; + } + break; + } diff --git a/queue-4.9/net-sched-gred-pass-the-right-attribute-to-gred_change_table_def.patch b/queue-4.9/net-sched-gred-pass-the-right-attribute-to-gred_change_table_def.patch new file mode 100644 index 00000000000..307bdcad4e2 --- /dev/null +++ b/queue-4.9/net-sched-gred-pass-the-right-attribute-to-gred_change_table_def.patch @@ -0,0 +1,54 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Jakub Kicinski +Date: Fri, 26 Oct 2018 15:51:06 -0700 +Subject: net: sched: gred: pass the right attribute to gred_change_table_def() + +From: Jakub Kicinski + +[ Upstream commit 38b4f18d56372e1e21771ab7b0357b853330186c ] + +gred_change_table_def() takes a pointer to TCA_GRED_DPS attribute, +and expects it will be able to interpret its contents as +struct tc_gred_sopt. Pass the correct gred attribute, instead of +TCA_OPTIONS. + +This bug meant the table definition could never be changed after +Qdisc was initialized (unless whatever TCA_OPTIONS contained both +passed netlink validation and was a valid struct tc_gred_sopt...). + +Old behaviour: +$ ip link add type dummy +$ tc qdisc replace dev dummy0 parent root handle 7: \ + gred setup vqs 4 default 0 +$ tc qdisc replace dev dummy0 parent root handle 7: \ + gred setup vqs 4 default 0 +RTNETLINK answers: Invalid argument + +Now: +$ ip link add type dummy +$ tc qdisc replace dev dummy0 parent root handle 7: \ + gred setup vqs 4 default 0 +$ tc qdisc replace dev dummy0 parent root handle 7: \ + gred setup vqs 4 default 0 +$ tc qdisc replace dev dummy0 parent root handle 7: \ + gred setup vqs 4 default 0 + +Fixes: f62d6b936df5 ("[PKT_SCHED]: GRED: Use central VQ change procedure") +Signed-off-by: Jakub Kicinski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_gred.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sched/sch_gred.c ++++ b/net/sched/sch_gred.c +@@ -411,7 +411,7 @@ static int gred_change(struct Qdisc *sch + if (tb[TCA_GRED_PARMS] == NULL && tb[TCA_GRED_STAB] == NULL) { + if (tb[TCA_GRED_LIMIT] != NULL) + sch->limit = nla_get_u32(tb[TCA_GRED_LIMIT]); +- return gred_change_table_def(sch, opt); ++ return gred_change_table_def(sch, tb[TCA_GRED_DPS]); + } + + if (tb[TCA_GRED_PARMS] == NULL || diff --git a/queue-4.9/net-socket-fix-a-missing-check-bug.patch b/queue-4.9/net-socket-fix-a-missing-check-bug.patch new file mode 100644 index 00000000000..c8a13ec0d4f --- /dev/null +++ b/queue-4.9/net-socket-fix-a-missing-check-bug.patch @@ -0,0 +1,56 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Wenwen Wang +Date: Thu, 18 Oct 2018 09:36:46 -0500 +Subject: net: socket: fix a missing-check bug + +From: Wenwen Wang + +[ Upstream commit b6168562c8ce2bd5a30e213021650422e08764dc ] + +In ethtool_ioctl(), the ioctl command 'ethcmd' is checked through a switch +statement to see whether it is necessary to pre-process the ethtool +structure, because, as mentioned in the comment, the structure +ethtool_rxnfc is defined with padding. If yes, a user-space buffer 'rxnfc' +is allocated through compat_alloc_user_space(). One thing to note here is +that, if 'ethcmd' is ETHTOOL_GRXCLSRLALL, the size of the buffer 'rxnfc' is +partially determined by 'rule_cnt', which is actually acquired from the +user-space buffer 'compat_rxnfc', i.e., 'compat_rxnfc->rule_cnt', through +get_user(). After 'rxnfc' is allocated, the data in the original user-space +buffer 'compat_rxnfc' is then copied to 'rxnfc' through copy_in_user(), +including the 'rule_cnt' field. However, after this copy, no check is +re-enforced on 'rxnfc->rule_cnt'. So it is possible that a malicious user +race to change the value in the 'compat_rxnfc->rule_cnt' between these two +copies. Through this way, the attacker can bypass the previous check on +'rule_cnt' and inject malicious data. This can cause undefined behavior of +the kernel and introduce potential security risk. + +This patch avoids the above issue via copying the value acquired by +get_user() to 'rxnfc->rule_cn', if 'ethcmd' is ETHTOOL_GRXCLSRLALL. + +Signed-off-by: Wenwen Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/socket.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/net/socket.c ++++ b/net/socket.c +@@ -2774,9 +2774,14 @@ static int ethtool_ioctl(struct net *net + copy_in_user(&rxnfc->fs.ring_cookie, + &compat_rxnfc->fs.ring_cookie, + (void __user *)(&rxnfc->fs.location + 1) - +- (void __user *)&rxnfc->fs.ring_cookie) || +- copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt, +- sizeof(rxnfc->rule_cnt))) ++ (void __user *)&rxnfc->fs.ring_cookie)) ++ return -EFAULT; ++ if (ethcmd == ETHTOOL_GRXCLSRLALL) { ++ if (put_user(rule_cnt, &rxnfc->rule_cnt)) ++ return -EFAULT; ++ } else if (copy_in_user(&rxnfc->rule_cnt, ++ &compat_rxnfc->rule_cnt, ++ sizeof(rxnfc->rule_cnt))) + return -EFAULT; + } + diff --git a/queue-4.9/net-stmmac-fix-stmmac_mdio_reset-when-building-stmmac-as-modules.patch b/queue-4.9/net-stmmac-fix-stmmac_mdio_reset-when-building-stmmac-as-modules.patch new file mode 100644 index 00000000000..9432abe6b06 --- /dev/null +++ b/queue-4.9/net-stmmac-fix-stmmac_mdio_reset-when-building-stmmac-as-modules.patch @@ -0,0 +1,43 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Niklas Cassel +Date: Wed, 31 Oct 2018 16:08:10 +0100 +Subject: net: stmmac: Fix stmmac_mdio_reset() when building stmmac as modules + +From: Niklas Cassel + +[ Upstream commit 30549aab146ccb1275230c3b4b4bc6b4181fd54e ] + +When building stmmac, it is only possible to select CONFIG_DWMAC_GENERIC, +or any of the glue drivers, when CONFIG_STMMAC_PLATFORM is set. +The only exception is CONFIG_STMMAC_PCI. + +When calling of_mdiobus_register(), it will call our ->reset() +callback, which is set to stmmac_mdio_reset(). + +Most of the code in stmmac_mdio_reset() is protected by a +"#if defined(CONFIG_STMMAC_PLATFORM)", which will evaluate +to false when CONFIG_STMMAC_PLATFORM=m. + +Because of this, the phy reset gpio will only be pulled when +stmmac is built as built-in, but not when built as modules. + +Fix this by using "#if IS_ENABLED()" instead of "#if defined()". + +Signed-off-by: Niklas Cassel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +@@ -216,7 +216,7 @@ static int stmmac_mdio_write_gmac4(struc + */ + int stmmac_mdio_reset(struct mii_bus *bus) + { +-#if defined(CONFIG_STMMAC_PLATFORM) ++#if IS_ENABLED(CONFIG_STMMAC_PLATFORM) + struct net_device *ndev = bus->priv; + struct stmmac_priv *priv = netdev_priv(ndev); + unsigned int mii_address = priv->hw->mii.addr; diff --git a/queue-4.9/net-udp-fix-handling-of-checksum_complete-packets.patch b/queue-4.9/net-udp-fix-handling-of-checksum_complete-packets.patch new file mode 100644 index 00000000000..8c7d397f065 --- /dev/null +++ b/queue-4.9/net-udp-fix-handling-of-checksum_complete-packets.patch @@ -0,0 +1,146 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Sean Tranchetti +Date: Tue, 23 Oct 2018 16:04:31 -0600 +Subject: net: udp: fix handling of CHECKSUM_COMPLETE packets + +From: Sean Tranchetti + +[ Upstream commit db4f1be3ca9b0ef7330763d07bf4ace83ad6f913 ] + +Current handling of CHECKSUM_COMPLETE packets by the UDP stack is +incorrect for any packet that has an incorrect checksum value. + +udp4/6_csum_init() will both make a call to +__skb_checksum_validate_complete() to initialize/validate the csum +field when receiving a CHECKSUM_COMPLETE packet. When this packet +fails validation, skb->csum will be overwritten with the pseudoheader +checksum so the packet can be fully validated by software, but the +skb->ip_summed value will be left as CHECKSUM_COMPLETE so that way +the stack can later warn the user about their hardware spewing bad +checksums. Unfortunately, leaving the SKB in this state can cause +problems later on in the checksum calculation. + +Since the the packet is still marked as CHECKSUM_COMPLETE, +udp_csum_pull_header() will SUBTRACT the checksum of the UDP header +from skb->csum instead of adding it, leaving us with a garbage value +in that field. Once we try to copy the packet to userspace in the +udp4/6_recvmsg(), we'll make a call to skb_copy_and_csum_datagram_msg() +to checksum the packet data and add it in the garbage skb->csum value +to perform our final validation check. + +Since the value we're validating is not the proper checksum, it's possible +that the folded value could come out to 0, causing us not to drop the +packet. Instead, we believe that the packet was checksummed incorrectly +by hardware since skb->ip_summed is still CHECKSUM_COMPLETE, and we attempt +to warn the user with netdev_rx_csum_fault(skb->dev); + +Unfortunately, since this is the UDP path, skb->dev has been overwritten +by skb->dev_scratch and is no longer a valid pointer, so we end up +reading invalid memory. + +This patch addresses this problem in two ways: + 1) Do not use the dev pointer when calling netdev_rx_csum_fault() + from skb_copy_and_csum_datagram_msg(). Since this gets called + from the UDP path where skb->dev has been overwritten, we have + no way of knowing if the pointer is still valid. Also for the + sake of consistency with the other uses of + netdev_rx_csum_fault(), don't attempt to call it if the + packet was checksummed by software. + + 2) Add better CHECKSUM_COMPLETE handling to udp4/6_csum_init(). + If we receive a packet that's CHECKSUM_COMPLETE that fails + verification (i.e. skb->csum_valid == 0), check who performed + the calculation. It's possible that the checksum was done in + software by the network stack earlier (such as Netfilter's + CONNTRACK module), and if that says the checksum is bad, + we can drop the packet immediately instead of waiting until + we try and copy it to userspace. Otherwise, we need to + mark the SKB as CHECKSUM_NONE, since the skb->csum field + no longer contains the full packet checksum after the + call to __skb_checksum_validate_complete(). + +Fixes: e6afc8ace6dd ("udp: remove headers from UDP packets before queueing") +Fixes: c84d949057ca ("udp: copy skb->truesize in the first cache line") +Cc: Sam Kumar +Cc: Eric Dumazet +Signed-off-by: Sean Tranchetti +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/datagram.c | 5 +++-- + net/ipv4/udp.c | 20 ++++++++++++++++++-- + net/ipv6/ip6_checksum.c | 20 ++++++++++++++++++-- + 3 files changed, 39 insertions(+), 6 deletions(-) + +--- a/net/core/datagram.c ++++ b/net/core/datagram.c +@@ -754,8 +754,9 @@ int skb_copy_and_csum_datagram_msg(struc + return -EINVAL; + } + +- if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) +- netdev_rx_csum_fault(skb->dev); ++ if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && ++ !skb->csum_complete_sw) ++ netdev_rx_csum_fault(NULL); + } + return 0; + fault: +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1726,8 +1726,24 @@ static inline int udp4_csum_init(struct + /* Note, we are only interested in != 0 or == 0, thus the + * force to int. + */ +- return (__force int)skb_checksum_init_zero_check(skb, proto, uh->check, +- inet_compute_pseudo); ++ err = (__force int)skb_checksum_init_zero_check(skb, proto, uh->check, ++ inet_compute_pseudo); ++ if (err) ++ return err; ++ ++ if (skb->ip_summed == CHECKSUM_COMPLETE && !skb->csum_valid) { ++ /* If SW calculated the value, we know it's bad */ ++ if (skb->csum_complete_sw) ++ return 1; ++ ++ /* HW says the value is bad. Let's validate that. ++ * skb->csum is no longer the full packet checksum, ++ * so don't treat it as such. ++ */ ++ skb_checksum_complete_unset(skb); ++ } ++ ++ return 0; + } + + /* wrapper for udp_queue_rcv_skb tacking care of csum conversion and +--- a/net/ipv6/ip6_checksum.c ++++ b/net/ipv6/ip6_checksum.c +@@ -87,8 +87,24 @@ int udp6_csum_init(struct sk_buff *skb, + * Note, we are only interested in != 0 or == 0, thus the + * force to int. + */ +- return (__force int)skb_checksum_init_zero_check(skb, proto, uh->check, +- ip6_compute_pseudo); ++ err = (__force int)skb_checksum_init_zero_check(skb, proto, uh->check, ++ ip6_compute_pseudo); ++ if (err) ++ return err; ++ ++ if (skb->ip_summed == CHECKSUM_COMPLETE && !skb->csum_valid) { ++ /* If SW calculated the value, we know it's bad */ ++ if (skb->csum_complete_sw) ++ return 1; ++ ++ /* HW says the value is bad. Let's validate that. ++ * skb->csum is no longer the full packet checksum, ++ * so don't treat is as such. ++ */ ++ skb_checksum_complete_unset(skb); ++ } ++ ++ return 0; + } + EXPORT_SYMBOL(udp6_csum_init); + diff --git a/queue-4.9/r8169-fix-napi-handling-under-high-load.patch b/queue-4.9/r8169-fix-napi-handling-under-high-load.patch new file mode 100644 index 00000000000..574d04a98de --- /dev/null +++ b/queue-4.9/r8169-fix-napi-handling-under-high-load.patch @@ -0,0 +1,52 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Heiner Kallweit +Date: Thu, 18 Oct 2018 19:56:01 +0200 +Subject: r8169: fix NAPI handling under high load + +From: Heiner Kallweit + +[ Upstream commit 6b839b6cf9eada30b086effb51e5d6076bafc761 ] + +rtl_rx() and rtl_tx() are called only if the respective bits are set +in the interrupt status register. Under high load NAPI may not be +able to process all data (work_done == budget) and it will schedule +subsequent calls to the poll callback. +rtl_ack_events() however resets the bits in the interrupt status +register, therefore subsequent calls to rtl8169_poll() won't call +rtl_rx() and rtl_tx() - chip interrupts are still disabled. + +Fix this by calling rtl_rx() and rtl_tx() independent of the bits +set in the interrupt status register. Both functions will detect +if there's nothing to do for them. + +Fixes: da78dbff2e05 ("r8169: remove work from irq handler.") +Signed-off-by: Heiner Kallweit +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/realtek/r8169.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -7559,17 +7559,15 @@ static int rtl8169_poll(struct napi_stru + struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); + struct net_device *dev = tp->dev; + u16 enable_mask = RTL_EVENT_NAPI | tp->event_slow; +- int work_done= 0; ++ int work_done; + u16 status; + + status = rtl_get_events(tp); + rtl_ack_events(tp, status & ~tp->event_slow); + +- if (status & RTL_EVENT_NAPI_RX) +- work_done = rtl_rx(dev, tp, (u32) budget); ++ work_done = rtl_rx(dev, tp, (u32) budget); + +- if (status & RTL_EVENT_NAPI_TX) +- rtl_tx(dev, tp); ++ rtl_tx(dev, tp); + + if (status & tp->event_slow) { + enable_mask &= ~tp->event_slow; diff --git a/queue-4.9/rtnetlink-disallow-fdb-configuration-for-non-ethernet-device.patch b/queue-4.9/rtnetlink-disallow-fdb-configuration-for-non-ethernet-device.patch new file mode 100644 index 00000000000..58c7c39c378 --- /dev/null +++ b/queue-4.9/rtnetlink-disallow-fdb-configuration-for-non-ethernet-device.patch @@ -0,0 +1,124 @@ +From foo@baz Fri Nov 2 09:44:43 CET 2018 +From: Ido Schimmel +Date: Mon, 29 Oct 2018 20:36:43 +0000 +Subject: rtnetlink: Disallow FDB configuration for non-Ethernet device + +From: Ido Schimmel + +[ Upstream commit da71577545a52be3e0e9225a946e5fd79cfab015 ] + +When an FDB entry is configured, the address is validated to have the +length of an Ethernet address, but the device for which the address is +configured can be of any type. + +The above can result in the use of uninitialized memory when the address +is later compared against existing addresses since 'dev->addr_len' is +used and it may be greater than ETH_ALEN, as with ip6tnl devices. + +Fix this by making sure that FDB entries are only configured for +Ethernet devices. + +BUG: KMSAN: uninit-value in memcmp+0x11d/0x180 lib/string.c:863 +CPU: 1 PID: 4318 Comm: syz-executor998 Not tainted 4.19.0-rc3+ #49 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS +Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x14b/0x190 lib/dump_stack.c:113 + kmsan_report+0x183/0x2b0 mm/kmsan/kmsan.c:956 + __msan_warning+0x70/0xc0 mm/kmsan/kmsan_instr.c:645 + memcmp+0x11d/0x180 lib/string.c:863 + dev_uc_add_excl+0x165/0x7b0 net/core/dev_addr_lists.c:464 + ndo_dflt_fdb_add net/core/rtnetlink.c:3463 [inline] + rtnl_fdb_add+0x1081/0x1270 net/core/rtnetlink.c:3558 + rtnetlink_rcv_msg+0xa0b/0x1530 net/core/rtnetlink.c:4715 + netlink_rcv_skb+0x36e/0x5f0 net/netlink/af_netlink.c:2454 + rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:4733 + netlink_unicast_kernel net/netlink/af_netlink.c:1317 [inline] + netlink_unicast+0x1638/0x1720 net/netlink/af_netlink.c:1343 + netlink_sendmsg+0x1205/0x1290 net/netlink/af_netlink.c:1908 + sock_sendmsg_nosec net/socket.c:621 [inline] + sock_sendmsg net/socket.c:631 [inline] + ___sys_sendmsg+0xe70/0x1290 net/socket.c:2114 + __sys_sendmsg net/socket.c:2152 [inline] + __do_sys_sendmsg net/socket.c:2161 [inline] + __se_sys_sendmsg+0x2a3/0x3d0 net/socket.c:2159 + __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2159 + do_syscall_64+0xb8/0x100 arch/x86/entry/common.c:291 + entry_SYSCALL_64_after_hwframe+0x63/0xe7 +RIP: 0033:0x440ee9 +Code: e8 cc ab 02 00 48 83 c4 18 c3 0f 1f 80 00 00 00 00 48 89 f8 48 89 f7 +48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff +ff 0f 83 bb 0a fc ff c3 66 2e 0f 1f 84 00 00 00 00 +RSP: 002b:00007fff6a93b518 EFLAGS: 00000213 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 0000000000440ee9 +RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000003 +RBP: 0000000000000000 R08: 00000000004002c8 R09: 00000000004002c8 +R10: 00000000004002c8 R11: 0000000000000213 R12: 000000000000b4b0 +R13: 0000000000401ec0 R14: 0000000000000000 R15: 0000000000000000 + +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:256 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:181 + kmsan_kmalloc+0x98/0x100 mm/kmsan/kmsan_hooks.c:91 + kmsan_slab_alloc+0x10/0x20 mm/kmsan/kmsan_hooks.c:100 + slab_post_alloc_hook mm/slab.h:446 [inline] + slab_alloc_node mm/slub.c:2718 [inline] + __kmalloc_node_track_caller+0x9e7/0x1160 mm/slub.c:4351 + __kmalloc_reserve net/core/skbuff.c:138 [inline] + __alloc_skb+0x2f5/0x9e0 net/core/skbuff.c:206 + alloc_skb include/linux/skbuff.h:996 [inline] + netlink_alloc_large_skb net/netlink/af_netlink.c:1189 [inline] + netlink_sendmsg+0xb49/0x1290 net/netlink/af_netlink.c:1883 + sock_sendmsg_nosec net/socket.c:621 [inline] + sock_sendmsg net/socket.c:631 [inline] + ___sys_sendmsg+0xe70/0x1290 net/socket.c:2114 + __sys_sendmsg net/socket.c:2152 [inline] + __do_sys_sendmsg net/socket.c:2161 [inline] + __se_sys_sendmsg+0x2a3/0x3d0 net/socket.c:2159 + __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2159 + do_syscall_64+0xb8/0x100 arch/x86/entry/common.c:291 + entry_SYSCALL_64_after_hwframe+0x63/0xe7 + +v2: +* Make error message more specific (David) + +Fixes: 090096bf3db1 ("net: generic fdb support for drivers without ndo_fdb_") +Signed-off-by: Ido Schimmel +Reported-and-tested-by: syzbot+3a288d5f5530b901310e@syzkaller.appspotmail.com +Reported-and-tested-by: syzbot+d53ab4e92a1db04110ff@syzkaller.appspotmail.com +Cc: Vlad Yasevich +Cc: David Ahern +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/rtnetlink.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -2987,6 +2987,11 @@ static int rtnl_fdb_add(struct sk_buff * + return -EINVAL; + } + ++ if (dev->type != ARPHRD_ETHER) { ++ NL_SET_ERR_MSG(extack, "FDB add only supported for Ethernet devices"); ++ return -EINVAL; ++ } ++ + addr = nla_data(tb[NDA_LLADDR]); + + err = fdb_vid_parse(tb[NDA_VLAN], &vid); +@@ -3090,6 +3095,11 @@ static int rtnl_fdb_del(struct sk_buff * + return -EINVAL; + } + ++ if (dev->type != ARPHRD_ETHER) { ++ NL_SET_ERR_MSG(extack, "FDB delete only supported for Ethernet devices"); ++ return -EINVAL; ++ } ++ + addr = nla_data(tb[NDA_LLADDR]); + + err = fdb_vid_parse(tb[NDA_VLAN], &vid); diff --git a/queue-4.9/sctp-fix-race-on-sctp_id2asoc.patch b/queue-4.9/sctp-fix-race-on-sctp_id2asoc.patch new file mode 100644 index 00000000000..4f8a80d4f34 --- /dev/null +++ b/queue-4.9/sctp-fix-race-on-sctp_id2asoc.patch @@ -0,0 +1,62 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Marcelo Ricardo Leitner +Date: Tue, 16 Oct 2018 15:18:17 -0300 +Subject: sctp: fix race on sctp_id2asoc + +From: Marcelo Ricardo Leitner + +[ Upstream commit b336decab22158937975293aea79396525f92bb3 ] + +syzbot reported an use-after-free involving sctp_id2asoc. Dmitry Vyukov +helped to root cause it and it is because of reading the asoc after it +was freed: + + CPU 1 CPU 2 +(working on socket 1) (working on socket 2) + sctp_association_destroy +sctp_id2asoc + spin lock + grab the asoc from idr + spin unlock + spin lock + remove asoc from idr + spin unlock + free(asoc) + if asoc->base.sk != sk ... [*] + +This can only be hit if trying to fetch asocs from different sockets. As +we have a single IDR for all asocs, in all SCTP sockets, their id is +unique on the system. An application can try to send stuff on an id +that matches on another socket, and the if in [*] will protect from such +usage. But it didn't consider that as that asoc may belong to another +socket, it may be freed in parallel (read: under another socket lock). + +We fix it by moving the checks in [*] into the protected region. This +fixes it because the asoc cannot be freed while the lock is held. + +Reported-by: syzbot+c7dd55d7aec49d48e49a@syzkaller.appspotmail.com +Acked-by: Dmitry Vyukov +Signed-off-by: Marcelo Ricardo Leitner +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -248,11 +248,10 @@ struct sctp_association *sctp_id2assoc(s + + spin_lock_bh(&sctp_assocs_id_lock); + asoc = (struct sctp_association *)idr_find(&sctp_assocs_id, (int)id); ++ if (asoc && (asoc->base.sk != sk || asoc->base.dead)) ++ asoc = NULL; + spin_unlock_bh(&sctp_assocs_id_lock); + +- if (!asoc || (asoc->base.sk != sk) || asoc->base.dead) +- return NULL; +- + return asoc; + } + diff --git a/queue-4.9/series b/queue-4.9/series index a6a28e5df4b..cd6e67ddad3 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -135,3 +135,20 @@ revert-netfilter-ipv6-nf_defrag-drop-skb-dst-before-.patch perf-tools-disable-parallelism-for-make-clean.patch bridge-do-not-add-port-to-router-list-when-receives-query-with-source-0.0.0.0.patch net-bridge-remove-ipv6-zero-address-check-in-mcast-queries.patch +ipv6-mcast-fix-a-use-after-free-in-inet6_mc_check.patch +ipv6-ndisc-preserve-ipv6-control-buffer-if-protocol-error-handlers-are-called.patch +llc-set-sock_rcu_free-in-llc_sap_add_socket.patch +net-ipv6-fix-index-counter-for-unicast-addresses-in-in6_dump_addrs.patch +net-sched-gred-pass-the-right-attribute-to-gred_change_table_def.patch +net-socket-fix-a-missing-check-bug.patch +net-stmmac-fix-stmmac_mdio_reset-when-building-stmmac-as-modules.patch +net-udp-fix-handling-of-checksum_complete-packets.patch +r8169-fix-napi-handling-under-high-load.patch +sctp-fix-race-on-sctp_id2asoc.patch +vhost-fix-spectre-v1-vulnerability.patch +ethtool-fix-a-privilege-escalation-bug.patch +bonding-fix-length-of-actor-system.patch +net-drop-skb-on-failure-in-ip_check_defrag.patch +net-fix-pskb_trim_rcsum_slow-with-odd-trim-offset.patch +rtnetlink-disallow-fdb-configuration-for-non-ethernet-device.patch +ip6_tunnel-fix-encapsulation-layout.patch diff --git a/queue-4.9/vhost-fix-spectre-v1-vulnerability.patch b/queue-4.9/vhost-fix-spectre-v1-vulnerability.patch new file mode 100644 index 00000000000..633372a0fa2 --- /dev/null +++ b/queue-4.9/vhost-fix-spectre-v1-vulnerability.patch @@ -0,0 +1,42 @@ +From foo@baz Fri Nov 2 10:04:04 CET 2018 +From: Jason Wang +Date: Tue, 30 Oct 2018 14:10:49 +0800 +Subject: vhost: Fix Spectre V1 vulnerability + +From: Jason Wang + +[ Upstream commit ff002269a4ee9c769dbf9365acef633ebcbd6cbe ] + +The idx in vhost_vring_ioctl() was controlled by userspace, hence a +potential exploitation of the Spectre variant 1 vulnerability. + +Fixing this by sanitizing idx before using it to index d->vqs. + +Cc: Michael S. Tsirkin +Cc: Josh Poimboeuf +Cc: Andrea Arcangeli +Signed-off-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/vhost.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #include "vhost.h" + +@@ -1289,6 +1290,7 @@ long vhost_vring_ioctl(struct vhost_dev + if (idx >= d->nvqs) + return -ENOBUFS; + ++ idx = array_index_nospec(idx, d->nvqs); + vq = d->vqs[idx]; + + mutex_lock(&vq->mutex); -- 2.39.5