From: Greg Kroah-Hartman Date: Wed, 19 Feb 2020 20:32:54 +0000 (+0100) Subject: 5.5-stable patches X-Git-Tag: v4.19.106~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9b331c8bd5476f9395b3188da3da94adb606c36a;p=thirdparty%2Fkernel%2Fstable-queue.git 5.5-stable patches added patches: core-don-t-skip-generic-xdp-program-execution-for-cloned-skbs.patch enic-prevent-waking-up-stopped-tx-queues-over-watchdog-reset.patch net-dsa-tag_qca-make-sure-there-is-headroom-for-tag.patch net-sched-flower-add-missing-validation-of-tca_flower_flags.patch net-sched-matchall-add-missing-validation-of-tca_matchall_flags.patch net-smc-fix-leak-of-kernel-memory-to-user-space.patch --- diff --git a/queue-5.5/core-don-t-skip-generic-xdp-program-execution-for-cloned-skbs.patch b/queue-5.5/core-don-t-skip-generic-xdp-program-execution-for-cloned-skbs.patch new file mode 100644 index 00000000000..58e4aee5f51 --- /dev/null +++ b/queue-5.5/core-don-t-skip-generic-xdp-program-execution-for-cloned-skbs.patch @@ -0,0 +1,136 @@ +From foo@baz Wed 19 Feb 2020 09:31:58 PM CET +From: "Toke Høiland-Jørgensen" +Date: Mon, 10 Feb 2020 17:10:46 +0100 +Subject: core: Don't skip generic XDP program execution for cloned SKBs + +From: "Toke Høiland-Jørgensen" + +[ Upstream commit ad1e03b2b3d4430baaa109b77bc308dc73050de3 ] + +The current generic XDP handler skips execution of XDP programs entirely if +an SKB is marked as cloned. This leads to some surprising behaviour, as +packets can end up being cloned in various ways, which will make an XDP +program not see all the traffic on an interface. + +This was discovered by a simple test case where an XDP program that always +returns XDP_DROP is installed on a veth device. When combining this with +the Scapy packet sniffer (which uses an AF_PACKET) socket on the sending +side, SKBs reliably end up in the cloned state, causing them to be passed +through to the receiving interface instead of being dropped. A minimal +reproducer script for this is included below. + +This patch fixed the issue by simply triggering the existing linearisation +code for cloned SKBs instead of skipping the XDP program execution. This +behaviour is in line with the behaviour of the native XDP implementation +for the veth driver, which will reallocate and copy the SKB data if the SKB +is marked as shared. + +Reproducer Python script (requires BCC and Scapy): + +from scapy.all import TCP, IP, Ether, sendp, sniff, AsyncSniffer, Raw, UDP +from bcc import BPF +import time, sys, subprocess, shlex + +SKB_MODE = (1 << 1) +DRV_MODE = (1 << 2) +PYTHON=sys.executable + +def client(): + time.sleep(2) + # Sniffing on the sender causes skb_cloned() to be set + s = AsyncSniffer() + s.start() + + for p in range(10): + sendp(Ether(dst="aa:aa:aa:aa:aa:aa", src="cc:cc:cc:cc:cc:cc")/IP()/UDP()/Raw("Test"), + verbose=False) + time.sleep(0.1) + + s.stop() + return 0 + +def server(mode): + prog = BPF(text="int dummy_drop(struct xdp_md *ctx) {return XDP_DROP;}") + func = prog.load_func("dummy_drop", BPF.XDP) + prog.attach_xdp("a_to_b", func, mode) + + time.sleep(1) + + s = sniff(iface="a_to_b", count=10, timeout=15) + if len(s): + print(f"Got {len(s)} packets - should have gotten 0") + return 1 + else: + print("Got no packets - as expected") + return 0 + +if len(sys.argv) < 2: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + +if sys.argv[1] == "client": + sys.exit(client()) +elif sys.argv[1] == "server": + mode = SKB_MODE if sys.argv[2] == 'skb' else DRV_MODE + sys.exit(server(mode)) +else: + try: + mode = sys.argv[1] + if mode not in ('skb', 'drv'): + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + print(f"Running in {mode} mode") + + for cmd in [ + 'ip netns add netns_a', + 'ip netns add netns_b', + 'ip -n netns_a link add a_to_b type veth peer name b_to_a netns netns_b', + # Disable ipv6 to make sure there's no address autoconf traffic + 'ip netns exec netns_a sysctl -qw net.ipv6.conf.a_to_b.disable_ipv6=1', + 'ip netns exec netns_b sysctl -qw net.ipv6.conf.b_to_a.disable_ipv6=1', + 'ip -n netns_a link set dev a_to_b address aa:aa:aa:aa:aa:aa', + 'ip -n netns_b link set dev b_to_a address cc:cc:cc:cc:cc:cc', + 'ip -n netns_a link set dev a_to_b up', + 'ip -n netns_b link set dev b_to_a up']: + subprocess.check_call(shlex.split(cmd)) + + server = subprocess.Popen(shlex.split(f"ip netns exec netns_a {PYTHON} {sys.argv[0]} server {mode}")) + client = subprocess.Popen(shlex.split(f"ip netns exec netns_b {PYTHON} {sys.argv[0]} client")) + + client.wait() + server.wait() + sys.exit(server.returncode) + + finally: + subprocess.run(shlex.split("ip netns delete netns_a")) + subprocess.run(shlex.split("ip netns delete netns_b")) + +Fixes: d445516966dc ("net: xdp: support xdp generic on virtual devices") +Reported-by: Stepan Horacek +Suggested-by: Paolo Abeni +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4477,14 +4477,14 @@ static u32 netif_receive_generic_xdp(str + /* Reinjected packets coming from act_mirred or similar should + * not get XDP generic processing. + */ +- if (skb_cloned(skb) || skb_is_tc_redirected(skb)) ++ if (skb_is_tc_redirected(skb)) + return XDP_PASS; + + /* XDP packets must be linear and must have sufficient headroom + * of XDP_PACKET_HEADROOM bytes. This is the guarantee that also + * native XDP provides, thus we need to do it here as well. + */ +- if (skb_is_nonlinear(skb) || ++ if (skb_cloned(skb) || skb_is_nonlinear(skb) || + skb_headroom(skb) < XDP_PACKET_HEADROOM) { + int hroom = XDP_PACKET_HEADROOM - skb_headroom(skb); + int troom = skb->tail + skb->data_len - skb->end; diff --git a/queue-5.5/enic-prevent-waking-up-stopped-tx-queues-over-watchdog-reset.patch b/queue-5.5/enic-prevent-waking-up-stopped-tx-queues-over-watchdog-reset.patch new file mode 100644 index 00000000000..7cafd65d6a4 --- /dev/null +++ b/queue-5.5/enic-prevent-waking-up-stopped-tx-queues-over-watchdog-reset.patch @@ -0,0 +1,57 @@ +From foo@baz Wed 19 Feb 2020 09:31:58 PM CET +From: Firo Yang +Date: Wed, 12 Feb 2020 06:09:17 +0100 +Subject: enic: prevent waking up stopped tx queues over watchdog reset + +From: Firo Yang + +[ Upstream commit 0f90522591fd09dd201065c53ebefdfe3c6b55cb ] + +Recent months, our customer reported several kernel crashes all +preceding with following message: +NETDEV WATCHDOG: eth2 (enic): transmit queue 0 timed out +Error message of one of those crashes: +BUG: unable to handle kernel paging request at ffffffffa007e090 + +After analyzing severl vmcores, I found that most of crashes are +caused by memory corruption. And all the corrupted memory areas +are overwritten by data of network packets. Moreover, I also found +that the tx queues were enabled over watchdog reset. + +After going through the source code, I found that in enic_stop(), +the tx queues stopped by netif_tx_disable() could be woken up over +a small time window between netif_tx_disable() and the +napi_disable() by the following code path: +napi_poll-> + enic_poll_msix_wq-> + vnic_cq_service-> + enic_wq_service-> + netif_wake_subqueue(enic->netdev, q_number)-> + test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &txq->state) +In turn, upper netowrk stack could queue skb to ENIC NIC though +enic_hard_start_xmit(). And this might introduce some race condition. + +Our customer comfirmed that this kind of kernel crash doesn't occur over +90 days since they applied this patch. + +Signed-off-by: Firo Yang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/cisco/enic/enic_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/cisco/enic/enic_main.c ++++ b/drivers/net/ethernet/cisco/enic/enic_main.c +@@ -2013,10 +2013,10 @@ static int enic_stop(struct net_device * + napi_disable(&enic->napi[i]); + + netif_carrier_off(netdev); +- netif_tx_disable(netdev); + if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX) + for (i = 0; i < enic->wq_count; i++) + napi_disable(&enic->napi[enic_cq_wq(enic, i)]); ++ netif_tx_disable(netdev); + + if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) + enic_dev_del_station_addr(enic); diff --git a/queue-5.5/net-dsa-tag_qca-make-sure-there-is-headroom-for-tag.patch b/queue-5.5/net-dsa-tag_qca-make-sure-there-is-headroom-for-tag.patch new file mode 100644 index 00000000000..b38bf641074 --- /dev/null +++ b/queue-5.5/net-dsa-tag_qca-make-sure-there-is-headroom-for-tag.patch @@ -0,0 +1,33 @@ +From foo@baz Wed 19 Feb 2020 09:31:58 PM CET +From: Per Forlin +Date: Thu, 13 Feb 2020 15:37:09 +0100 +Subject: net: dsa: tag_qca: Make sure there is headroom for tag + +From: Per Forlin + +[ Upstream commit 04fb91243a853dbde216d829c79d9632e52aa8d9 ] + +Passing tag size to skb_cow_head will make sure +there is enough headroom for the tag data. +This change does not introduce any overhead in case there +is already available headroom for tag. + +Signed-off-by: Per Forlin +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dsa/tag_qca.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/dsa/tag_qca.c ++++ b/net/dsa/tag_qca.c +@@ -33,7 +33,7 @@ static struct sk_buff *qca_tag_xmit(stru + struct dsa_port *dp = dsa_slave_to_port(dev); + u16 *phdr, hdr; + +- if (skb_cow_head(skb, 0) < 0) ++ if (skb_cow_head(skb, QCA_HDR_LEN) < 0) + return NULL; + + skb_push(skb, QCA_HDR_LEN); diff --git a/queue-5.5/net-sched-flower-add-missing-validation-of-tca_flower_flags.patch b/queue-5.5/net-sched-flower-add-missing-validation-of-tca_flower_flags.patch new file mode 100644 index 00000000000..830e4b67adc --- /dev/null +++ b/queue-5.5/net-sched-flower-add-missing-validation-of-tca_flower_flags.patch @@ -0,0 +1,33 @@ +From foo@baz Wed 19 Feb 2020 09:31:58 PM CET +From: Davide Caratti +Date: Tue, 11 Feb 2020 19:33:40 +0100 +Subject: net/sched: flower: add missing validation of TCA_FLOWER_FLAGS + +From: Davide Caratti + +[ Upstream commit e2debf0852c4d66ba1a8bde12869b196094c70a7 ] + +unlike other classifiers that can be offloaded (i.e. users can set flags +like 'skip_hw' and 'skip_sw'), 'cls_flower' doesn't validate the size of +netlink attribute 'TCA_FLOWER_FLAGS' provided by user: add a proper entry +to fl_policy. + +Fixes: 5b33f48842fa ("net/flower: Introduce hardware offload support") +Signed-off-by: Davide Caratti +Acked-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/cls_flower.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -691,6 +691,7 @@ static const struct nla_policy fl_policy + .len = 128 / BITS_PER_BYTE }, + [TCA_FLOWER_KEY_CT_LABELS_MASK] = { .type = NLA_BINARY, + .len = 128 / BITS_PER_BYTE }, ++ [TCA_FLOWER_FLAGS] = { .type = NLA_U32 }, + }; + + static const struct nla_policy diff --git a/queue-5.5/net-sched-matchall-add-missing-validation-of-tca_matchall_flags.patch b/queue-5.5/net-sched-matchall-add-missing-validation-of-tca_matchall_flags.patch new file mode 100644 index 00000000000..fd7063930a2 --- /dev/null +++ b/queue-5.5/net-sched-matchall-add-missing-validation-of-tca_matchall_flags.patch @@ -0,0 +1,33 @@ +From foo@baz Wed 19 Feb 2020 09:31:58 PM CET +From: Davide Caratti +Date: Tue, 11 Feb 2020 19:33:39 +0100 +Subject: net/sched: matchall: add missing validation of TCA_MATCHALL_FLAGS + +From: Davide Caratti + +[ Upstream commit 1afa3cc90f8fb745c777884d79eaa1001d6927a6 ] + +unlike other classifiers that can be offloaded (i.e. users can set flags +like 'skip_hw' and 'skip_sw'), 'cls_matchall' doesn't validate the size +of netlink attribute 'TCA_MATCHALL_FLAGS' provided by user: add a proper +entry to mall_policy. + +Fixes: b87f7936a932 ("net/sched: Add match-all classifier hw offloading.") +Signed-off-by: Davide Caratti +Acked-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/cls_matchall.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/sched/cls_matchall.c ++++ b/net/sched/cls_matchall.c +@@ -157,6 +157,7 @@ static void *mall_get(struct tcf_proto * + static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = { + [TCA_MATCHALL_UNSPEC] = { .type = NLA_UNSPEC }, + [TCA_MATCHALL_CLASSID] = { .type = NLA_U32 }, ++ [TCA_MATCHALL_FLAGS] = { .type = NLA_U32 }, + }; + + static int mall_set_parms(struct net *net, struct tcf_proto *tp, diff --git a/queue-5.5/net-smc-fix-leak-of-kernel-memory-to-user-space.patch b/queue-5.5/net-smc-fix-leak-of-kernel-memory-to-user-space.patch new file mode 100644 index 00000000000..5dd44086af1 --- /dev/null +++ b/queue-5.5/net-smc-fix-leak-of-kernel-memory-to-user-space.patch @@ -0,0 +1,111 @@ +From foo@baz Wed 19 Feb 2020 09:31:58 PM CET +From: Eric Dumazet +Date: Mon, 10 Feb 2020 11:36:13 -0800 +Subject: net/smc: fix leak of kernel memory to user space + +From: Eric Dumazet + +[ Upstream commit 457fed775c97ac2c0cd1672aaf2ff2c8a6235e87 ] + +As nlmsg_put() does not clear the memory that is reserved, +it this the caller responsability to make sure all of this +memory will be written, in order to not reveal prior content. + +While we are at it, we can provide the socket cookie even +if clsock is not set. + +syzbot reported : + +BUG: KMSAN: uninit-value in __arch_swab32 arch/x86/include/uapi/asm/swab.h:10 [inline] +BUG: KMSAN: uninit-value in __fswab32 include/uapi/linux/swab.h:59 [inline] +BUG: KMSAN: uninit-value in __swab32p include/uapi/linux/swab.h:179 [inline] +BUG: KMSAN: uninit-value in __be32_to_cpup include/uapi/linux/byteorder/little_endian.h:82 [inline] +BUG: KMSAN: uninit-value in get_unaligned_be32 include/linux/unaligned/access_ok.h:30 [inline] +BUG: KMSAN: uninit-value in ____bpf_skb_load_helper_32 net/core/filter.c:240 [inline] +BUG: KMSAN: uninit-value in ____bpf_skb_load_helper_32_no_cache net/core/filter.c:255 [inline] +BUG: KMSAN: uninit-value in bpf_skb_load_helper_32_no_cache+0x14a/0x390 net/core/filter.c:252 +CPU: 1 PID: 5262 Comm: syz-executor.5 Not tainted 5.5.0-rc5-syzkaller #0 +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+0x1c9/0x220 lib/dump_stack.c:118 + kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:118 + __msan_warning+0x58/0xa0 mm/kmsan/kmsan_instr.c:215 + __arch_swab32 arch/x86/include/uapi/asm/swab.h:10 [inline] + __fswab32 include/uapi/linux/swab.h:59 [inline] + __swab32p include/uapi/linux/swab.h:179 [inline] + __be32_to_cpup include/uapi/linux/byteorder/little_endian.h:82 [inline] + get_unaligned_be32 include/linux/unaligned/access_ok.h:30 [inline] + ____bpf_skb_load_helper_32 net/core/filter.c:240 [inline] + ____bpf_skb_load_helper_32_no_cache net/core/filter.c:255 [inline] + bpf_skb_load_helper_32_no_cache+0x14a/0x390 net/core/filter.c:252 + +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:144 [inline] + kmsan_internal_poison_shadow+0x66/0xd0 mm/kmsan/kmsan.c:127 + kmsan_kmalloc_large+0x73/0xc0 mm/kmsan/kmsan_hooks.c:128 + kmalloc_large_node_hook mm/slub.c:1406 [inline] + kmalloc_large_node+0x282/0x2c0 mm/slub.c:3841 + __kmalloc_node_track_caller+0x44b/0x1200 mm/slub.c:4368 + __kmalloc_reserve net/core/skbuff.c:141 [inline] + __alloc_skb+0x2fd/0xac0 net/core/skbuff.c:209 + alloc_skb include/linux/skbuff.h:1049 [inline] + netlink_dump+0x44b/0x1ab0 net/netlink/af_netlink.c:2224 + __netlink_dump_start+0xbb2/0xcf0 net/netlink/af_netlink.c:2352 + netlink_dump_start include/linux/netlink.h:233 [inline] + smc_diag_handler_dump+0x2ba/0x300 net/smc/smc_diag.c:242 + sock_diag_rcv_msg+0x211/0x610 net/core/sock_diag.c:256 + netlink_rcv_skb+0x451/0x650 net/netlink/af_netlink.c:2477 + sock_diag_rcv+0x63/0x80 net/core/sock_diag.c:275 + netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] + netlink_unicast+0xf9e/0x1100 net/netlink/af_netlink.c:1328 + netlink_sendmsg+0x1248/0x14d0 net/netlink/af_netlink.c:1917 + sock_sendmsg_nosec net/socket.c:639 [inline] + sock_sendmsg net/socket.c:659 [inline] + kernel_sendmsg+0x433/0x440 net/socket.c:679 + sock_no_sendpage+0x235/0x300 net/core/sock.c:2740 + kernel_sendpage net/socket.c:3776 [inline] + sock_sendpage+0x1e1/0x2c0 net/socket.c:937 + pipe_to_sendpage+0x38c/0x4c0 fs/splice.c:458 + splice_from_pipe_feed fs/splice.c:512 [inline] + __splice_from_pipe+0x539/0xed0 fs/splice.c:636 + splice_from_pipe fs/splice.c:671 [inline] + generic_splice_sendpage+0x1d5/0x2d0 fs/splice.c:844 + do_splice_from fs/splice.c:863 [inline] + do_splice fs/splice.c:1170 [inline] + __do_sys_splice fs/splice.c:1447 [inline] + __se_sys_splice+0x2380/0x3350 fs/splice.c:1427 + __x64_sys_splice+0x6e/0x90 fs/splice.c:1427 + do_syscall_64+0xb8/0x160 arch/x86/entry/common.c:296 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets") +Signed-off-by: Eric Dumazet +Cc: Ursula Braun +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/smc/smc_diag.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/smc/smc_diag.c ++++ b/net/smc/smc_diag.c +@@ -39,16 +39,15 @@ static void smc_diag_msg_common_fill(str + { + struct smc_sock *smc = smc_sk(sk); + ++ memset(r, 0, sizeof(*r)); + r->diag_family = sk->sk_family; ++ sock_diag_save_cookie(sk, r->id.idiag_cookie); + if (!smc->clcsock) + return; + r->id.idiag_sport = htons(smc->clcsock->sk->sk_num); + r->id.idiag_dport = smc->clcsock->sk->sk_dport; + r->id.idiag_if = smc->clcsock->sk->sk_bound_dev_if; +- sock_diag_save_cookie(sk, r->id.idiag_cookie); + if (sk->sk_protocol == SMCPROTO_SMC) { +- memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src)); +- memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst)); + r->id.idiag_src[0] = smc->clcsock->sk->sk_rcv_saddr; + r->id.idiag_dst[0] = smc->clcsock->sk->sk_daddr; + #if IS_ENABLED(CONFIG_IPV6)