From: Greg Kroah-Hartman Date: Tue, 22 May 2018 19:10:09 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.110~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9783ad81090719a558c521a43bd91a152dbf6de9;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: net-test-tailroom-before-appending-to-linear-skb.patch packet-in-packet_snd-start-writing-at-link-layer-allocation.patch sock_diag-fix-use-after-free-read-in-__sk_free.patch tcp-purge-write-queue-in-tcp_connect_init.patch --- diff --git a/queue-4.4/net-test-tailroom-before-appending-to-linear-skb.patch b/queue-4.4/net-test-tailroom-before-appending-to-linear-skb.patch new file mode 100644 index 00000000000..d64a92489cf --- /dev/null +++ b/queue-4.4/net-test-tailroom-before-appending-to-linear-skb.patch @@ -0,0 +1,54 @@ +From foo@baz Tue May 22 21:07:28 CEST 2018 +From: Willem de Bruijn +Date: Thu, 17 May 2018 13:13:29 -0400 +Subject: net: test tailroom before appending to linear skb + +From: Willem de Bruijn + +[ Upstream commit 113f99c3358564a0647d444c2ae34e8b1abfd5b9 ] + +Device features may change during transmission. In particular with +corking, a device may toggle scatter-gather in between allocating +and writing to an skb. + +Do not unconditionally assume that !NETIF_F_SG at write time implies +that the same held at alloc time and thus the skb has sufficient +tailroom. + +This issue predates git history. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: Eric Dumazet +Signed-off-by: Willem de Bruijn +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 3 ++- + net/ipv6/ip6_output.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -1062,7 +1062,8 @@ alloc_new_skb: + if (copy > length) + copy = length; + +- if (!(rt->dst.dev->features&NETIF_F_SG)) { ++ if (!(rt->dst.dev->features&NETIF_F_SG) && ++ skb_tailroom(skb) >= copy) { + unsigned int off; + + off = skb->len; +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1529,7 +1529,8 @@ alloc_new_skb: + if (copy > length) + copy = length; + +- if (!(rt->dst.dev->features&NETIF_F_SG)) { ++ if (!(rt->dst.dev->features&NETIF_F_SG) && ++ skb_tailroom(skb) >= copy) { + unsigned int off; + + off = skb->len; diff --git a/queue-4.4/packet-in-packet_snd-start-writing-at-link-layer-allocation.patch b/queue-4.4/packet-in-packet_snd-start-writing-at-link-layer-allocation.patch new file mode 100644 index 00000000000..f17ec483826 --- /dev/null +++ b/queue-4.4/packet-in-packet_snd-start-writing-at-link-layer-allocation.patch @@ -0,0 +1,56 @@ +From foo@baz Tue May 22 21:07:28 CEST 2018 +From: Willem de Bruijn +Date: Fri, 11 May 2018 13:24:25 -0400 +Subject: packet: in packet_snd start writing at link layer allocation + +From: Willem de Bruijn + +[ Upstream commit b84bbaf7a6c8cca24f8acf25a2c8e46913a947ba ] + +Packet sockets allow construction of packets shorter than +dev->hard_header_len to accommodate protocols with variable length +link layer headers. These packets are padded to dev->hard_header_len, +because some device drivers interpret that as a minimum packet size. + +packet_snd reserves dev->hard_header_len bytes on allocation. +SOCK_DGRAM sockets call skb_push in dev_hard_header() to ensure that +link layer headers are stored in the reserved range. SOCK_RAW sockets +do the same in tpacket_snd, but not in packet_snd. + +Syzbot was able to send a zero byte packet to a device with massive +116B link layer header, causing padding to cross over into skb_shinfo. +Fix this by writing from the start of the llheader reserved range also +in the case of packet_snd/SOCK_RAW. + +Update skb_set_network_header to the new offset. This also corrects +it for SOCK_DGRAM, where it incorrectly double counted reserve due to +the skb_push in dev_hard_header. + +Fixes: 9ed988cd5915 ("packet: validate variable length ll headers") +Reported-by: syzbot+71d74a5406d02057d559@syzkaller.appspotmail.com +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2771,13 +2771,15 @@ static int packet_snd(struct socket *soc + if (skb == NULL) + goto out_unlock; + +- skb_set_network_header(skb, reserve); ++ skb_reset_network_header(skb); + + err = -EINVAL; + if (sock->type == SOCK_DGRAM) { + offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len); + if (unlikely(offset < 0)) + goto out_free; ++ } else if (reserve) { ++ skb_push(skb, reserve); + } + + /* Returns -EFAULT on error */ diff --git a/queue-4.4/series b/queue-4.4/series index c9f4fb46cf7..08c8841aba0 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -68,3 +68,7 @@ arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch btrfs-fix-xattr-loss-after-power-failure.patch btrfs-fix-crash-when-trying-to-resume-balance-without-the-resume-flag.patch btrfs-fix-reading-stale-metadata-blocks-after-degraded-raid1-mounts.patch +net-test-tailroom-before-appending-to-linear-skb.patch +packet-in-packet_snd-start-writing-at-link-layer-allocation.patch +sock_diag-fix-use-after-free-read-in-__sk_free.patch +tcp-purge-write-queue-in-tcp_connect_init.patch diff --git a/queue-4.4/sock_diag-fix-use-after-free-read-in-__sk_free.patch b/queue-4.4/sock_diag-fix-use-after-free-read-in-__sk_free.patch new file mode 100644 index 00000000000..754349ba042 --- /dev/null +++ b/queue-4.4/sock_diag-fix-use-after-free-read-in-__sk_free.patch @@ -0,0 +1,128 @@ +From foo@baz Tue May 22 21:07:28 CEST 2018 +From: Eric Dumazet +Date: Fri, 18 May 2018 04:47:55 -0700 +Subject: sock_diag: fix use-after-free read in __sk_free + +From: Eric Dumazet + +[ Upstream commit 9709020c86f6bf8439ca3effc58cfca49a5de192 ] + +We must not call sock_diag_has_destroy_listeners(sk) on a socket +that has no reference on net structure. + +BUG: KASAN: use-after-free in sock_diag_has_destroy_listeners include/linux/sock_diag.h:75 [inline] +BUG: KASAN: use-after-free in __sk_free+0x329/0x340 net/core/sock.c:1609 +Read of size 8 at addr ffff88018a02e3a0 by task swapper/1/0 + +CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.17.0-rc5+ #54 +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+0x1b9/0x294 lib/dump_stack.c:113 + print_address_description+0x6c/0x20b mm/kasan/report.c:256 + kasan_report_error mm/kasan/report.c:354 [inline] + kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 + __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433 + sock_diag_has_destroy_listeners include/linux/sock_diag.h:75 [inline] + __sk_free+0x329/0x340 net/core/sock.c:1609 + sk_free+0x42/0x50 net/core/sock.c:1623 + sock_put include/net/sock.h:1664 [inline] + reqsk_free include/net/request_sock.h:116 [inline] + reqsk_put include/net/request_sock.h:124 [inline] + inet_csk_reqsk_queue_drop_and_put net/ipv4/inet_connection_sock.c:672 [inline] + reqsk_timer_handler+0xe27/0x10e0 net/ipv4/inet_connection_sock.c:739 + call_timer_fn+0x230/0x940 kernel/time/timer.c:1326 + expire_timers kernel/time/timer.c:1363 [inline] + __run_timers+0x79e/0xc50 kernel/time/timer.c:1666 + run_timer_softirq+0x4c/0x70 kernel/time/timer.c:1692 + __do_softirq+0x2e0/0xaf5 kernel/softirq.c:285 + invoke_softirq kernel/softirq.c:365 [inline] + irq_exit+0x1d1/0x200 kernel/softirq.c:405 + exiting_irq arch/x86/include/asm/apic.h:525 [inline] + smp_apic_timer_interrupt+0x17e/0x710 arch/x86/kernel/apic/apic.c:1052 + apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:863 + +RIP: 0010:native_safe_halt+0x6/0x10 arch/x86/include/asm/irqflags.h:54 +RSP: 0018:ffff8801d9ae7c38 EFLAGS: 00000282 ORIG_RAX: ffffffffffffff13 +RAX: dffffc0000000000 RBX: 1ffff1003b35cf8a RCX: 0000000000000000 +RDX: 1ffffffff11a30d0 RSI: 0000000000000001 RDI: ffffffff88d18680 +RBP: ffff8801d9ae7c38 R08: ffffed003b5e46c3 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000001 +R13: ffff8801d9ae7cf0 R14: ffffffff897bef20 R15: 0000000000000000 + arch_safe_halt arch/x86/include/asm/paravirt.h:94 [inline] + default_idle+0xc2/0x440 arch/x86/kernel/process.c:354 + arch_cpu_idle+0x10/0x20 arch/x86/kernel/process.c:345 + default_idle_call+0x6d/0x90 kernel/sched/idle.c:93 + cpuidle_idle_call kernel/sched/idle.c:153 [inline] + do_idle+0x395/0x560 kernel/sched/idle.c:262 + cpu_startup_entry+0x104/0x120 kernel/sched/idle.c:368 + start_secondary+0x426/0x5b0 arch/x86/kernel/smpboot.c:269 + secondary_startup_64+0xa5/0xb0 arch/x86/kernel/head_64.S:242 + +Allocated by task 4557: + save_stack+0x43/0xd0 mm/kasan/kasan.c:448 + set_track mm/kasan/kasan.c:460 [inline] + kasan_kmalloc+0xc4/0xe0 mm/kasan/kasan.c:553 + kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490 + kmem_cache_alloc+0x12e/0x760 mm/slab.c:3554 + kmem_cache_zalloc include/linux/slab.h:691 [inline] + net_alloc net/core/net_namespace.c:383 [inline] + copy_net_ns+0x159/0x4c0 net/core/net_namespace.c:423 + create_new_namespaces+0x69d/0x8f0 kernel/nsproxy.c:107 + unshare_nsproxy_namespaces+0xc3/0x1f0 kernel/nsproxy.c:206 + ksys_unshare+0x708/0xf90 kernel/fork.c:2408 + __do_sys_unshare kernel/fork.c:2476 [inline] + __se_sys_unshare kernel/fork.c:2474 [inline] + __x64_sys_unshare+0x31/0x40 kernel/fork.c:2474 + do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Freed by task 69: + save_stack+0x43/0xd0 mm/kasan/kasan.c:448 + set_track mm/kasan/kasan.c:460 [inline] + __kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521 + kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528 + __cache_free mm/slab.c:3498 [inline] + kmem_cache_free+0x86/0x2d0 mm/slab.c:3756 + net_free net/core/net_namespace.c:399 [inline] + net_drop_ns.part.14+0x11a/0x130 net/core/net_namespace.c:406 + net_drop_ns net/core/net_namespace.c:405 [inline] + cleanup_net+0x6a1/0xb20 net/core/net_namespace.c:541 + process_one_work+0xc1e/0x1b50 kernel/workqueue.c:2145 + worker_thread+0x1cc/0x1440 kernel/workqueue.c:2279 + kthread+0x345/0x410 kernel/kthread.c:240 + ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:412 + +The buggy address belongs to the object at ffff88018a02c140 + which belongs to the cache net_namespace of size 8832 +The buggy address is located 8800 bytes inside of + 8832-byte region [ffff88018a02c140, ffff88018a02e3c0) +The buggy address belongs to the page: +page:ffffea0006280b00 count:1 mapcount:0 mapping:ffff88018a02c140 index:0x0 compound_mapcount: 0 +flags: 0x2fffc0000008100(slab|head) +raw: 02fffc0000008100 ffff88018a02c140 0000000000000000 0000000100000001 +raw: ffffea00062a1320 ffffea0006268020 ffff8801d9bdde40 0000000000000000 +page dumped because: kasan: bad access detected + +Fixes: b922622ec6ef ("sock_diag: don't broadcast kernel sockets") +Signed-off-by: Eric Dumazet +Cc: Craig Gallek +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/sock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1474,7 +1474,7 @@ void sk_destruct(struct sock *sk) + + static void __sk_free(struct sock *sk) + { +- if (unlikely(sock_diag_has_destroy_listeners(sk) && sk->sk_net_refcnt)) ++ if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) + sock_diag_broadcast_destroy(sk); + else + sk_destruct(sk); diff --git a/queue-4.4/tcp-purge-write-queue-in-tcp_connect_init.patch b/queue-4.4/tcp-purge-write-queue-in-tcp_connect_init.patch new file mode 100644 index 00000000000..8f011424c8a --- /dev/null +++ b/queue-4.4/tcp-purge-write-queue-in-tcp_connect_init.patch @@ -0,0 +1,88 @@ +From foo@baz Tue May 22 21:07:28 CEST 2018 +From: Eric Dumazet +Date: Mon, 14 May 2018 21:14:26 -0700 +Subject: tcp: purge write queue in tcp_connect_init() + +From: Eric Dumazet + +[ Upstream commit 7f582b248d0a86bae5788c548d7bb5bca6f7691a ] + +syzkaller found a reliable way to crash the host, hitting a BUG() +in __tcp_retransmit_skb() + +Malicous MSG_FASTOPEN is the root cause. We need to purge write queue +in tcp_connect_init() at the point we init snd_una/write_seq. + +This patch also replaces the BUG() by a less intrusive WARN_ON_ONCE() + +kernel BUG at net/ipv4/tcp_output.c:2837! +invalid opcode: 0000 [#1] SMP KASAN +Dumping ftrace buffer: + (ftrace buffer empty) +Modules linked in: +CPU: 0 PID: 5276 Comm: syz-executor0 Not tainted 4.17.0-rc3+ #51 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +RIP: 0010:__tcp_retransmit_skb+0x2992/0x2eb0 net/ipv4/tcp_output.c:2837 +RSP: 0000:ffff8801dae06ff8 EFLAGS: 00010206 +RAX: ffff8801b9fe61c0 RBX: 00000000ffc18a16 RCX: ffffffff864e1a49 +RDX: 0000000000000100 RSI: ffffffff864e2e12 RDI: 0000000000000005 +RBP: ffff8801dae073a0 R08: ffff8801b9fe61c0 R09: ffffed0039c40dd2 +R10: ffffed0039c40dd2 R11: ffff8801ce206e93 R12: 00000000421eeaad +R13: ffff8801ce206d4e R14: ffff8801ce206cc0 R15: ffff8801cd4f4a80 +FS: 0000000000000000(0000) GS:ffff8801dae00000(0063) knlGS:00000000096bc900 +CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 +CR2: 0000000020000000 CR3: 00000001c47b6000 CR4: 00000000001406f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + tcp_retransmit_skb+0x2e/0x250 net/ipv4/tcp_output.c:2923 + tcp_retransmit_timer+0xc50/0x3060 net/ipv4/tcp_timer.c:488 + tcp_write_timer_handler+0x339/0x960 net/ipv4/tcp_timer.c:573 + tcp_write_timer+0x111/0x1d0 net/ipv4/tcp_timer.c:593 + call_timer_fn+0x230/0x940 kernel/time/timer.c:1326 + expire_timers kernel/time/timer.c:1363 [inline] + __run_timers+0x79e/0xc50 kernel/time/timer.c:1666 + run_timer_softirq+0x4c/0x70 kernel/time/timer.c:1692 + __do_softirq+0x2e0/0xaf5 kernel/softirq.c:285 + invoke_softirq kernel/softirq.c:365 [inline] + irq_exit+0x1d1/0x200 kernel/softirq.c:405 + exiting_irq arch/x86/include/asm/apic.h:525 [inline] + smp_apic_timer_interrupt+0x17e/0x710 arch/x86/kernel/apic/apic.c:1052 + apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:863 + +Fixes: cf60af03ca4e ("net-tcp: Fast Open client - sendmsg(MSG_FASTOPEN)") +Signed-off-by: Eric Dumazet +Cc: Yuchung Cheng +Cc: Neal Cardwell +Reported-by: syzbot +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_output.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2587,8 +2587,10 @@ int __tcp_retransmit_skb(struct sock *sk + return -EBUSY; + + if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) { +- if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) +- BUG(); ++ if (unlikely(before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))) { ++ WARN_ON_ONCE(1); ++ return -EINVAL; ++ } + if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq)) + return -ENOMEM; + } +@@ -3117,6 +3119,7 @@ static void tcp_connect_init(struct sock + sock_reset_flag(sk, SOCK_DONE); + tp->snd_wnd = 0; + tcp_init_wl(tp, 0); ++ tcp_write_queue_purge(sk); + tp->snd_una = tp->write_seq; + tp->snd_sml = tp->write_seq; + tp->snd_up = tp->write_seq;