From: Greg Kroah-Hartman Date: Thu, 14 Dec 2017 17:55:26 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v3.18.88~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6ecf35ca008a38c72e18af6dfe5dcdb14cf7f0a7;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: net-packet-fix-a-race-in-packet_bind-and-packet_notifier.patch packet-fix-crash-in-fanout_demux_rollover.patch rds-fix-null-pointer-dereference-in-__rds_rdma_map.patch sit-update-frag_off-info.patch tipc-fix-memory-leak-in-tipc_accept_from_sock.patch --- diff --git a/queue-4.4/net-packet-fix-a-race-in-packet_bind-and-packet_notifier.patch b/queue-4.4/net-packet-fix-a-race-in-packet_bind-and-packet_notifier.patch new file mode 100644 index 00000000000..1cebc2a9715 --- /dev/null +++ b/queue-4.4/net-packet-fix-a-race-in-packet_bind-and-packet_notifier.patch @@ -0,0 +1,93 @@ +From foo@baz Thu Dec 14 18:55:00 CET 2017 +From: Eric Dumazet +Date: Tue, 28 Nov 2017 08:03:30 -0800 +Subject: net/packet: fix a race in packet_bind() and packet_notifier() + +From: Eric Dumazet + + +[ Upstream commit 15fe076edea787807a7cdc168df832544b58eba6 ] + +syzbot reported crashes [1] and provided a C repro easing bug hunting. + +When/if packet_do_bind() calls __unregister_prot_hook() and releases +po->bind_lock, another thread can run packet_notifier() and process an +NETDEV_UP event. + +This calls register_prot_hook() and hooks again the socket right before +first thread is able to grab again po->bind_lock. + +Fixes this issue by temporarily setting po->num to 0, as suggested by +David Miller. + +[1] +dev_remove_pack: ffff8801bf16fa80 not found +------------[ cut here ]------------ +kernel BUG at net/core/dev.c:7945! ( BUG_ON(!list_empty(&dev->ptype_all)); ) +invalid opcode: 0000 [#1] SMP KASAN +Dumping ftrace buffer: + (ftrace buffer empty) +Modules linked in: +device syz0 entered promiscuous mode +CPU: 0 PID: 3161 Comm: syzkaller404108 Not tainted 4.14.0+ #190 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +task: ffff8801cc57a500 task.stack: ffff8801cc588000 +RIP: 0010:netdev_run_todo+0x772/0xae0 net/core/dev.c:7945 +RSP: 0018:ffff8801cc58f598 EFLAGS: 00010293 +RAX: ffff8801cc57a500 RBX: dffffc0000000000 RCX: ffffffff841f75b2 +RDX: 0000000000000000 RSI: 1ffff100398b1ede RDI: ffff8801bf1f8810 +device syz0 entered promiscuous mode +RBP: ffff8801cc58f898 R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: ffff8801bf1f8cd8 +R13: ffff8801cc58f870 R14: ffff8801bf1f8780 R15: ffff8801cc58f7f0 +FS: 0000000001716880(0000) GS:ffff8801db400000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000020b13000 CR3: 0000000005e25000 CR4: 00000000001406f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + rtnl_unlock+0xe/0x10 net/core/rtnetlink.c:106 + tun_detach drivers/net/tun.c:670 [inline] + tun_chr_close+0x49/0x60 drivers/net/tun.c:2845 + __fput+0x333/0x7f0 fs/file_table.c:210 + ____fput+0x15/0x20 fs/file_table.c:244 + task_work_run+0x199/0x270 kernel/task_work.c:113 + exit_task_work include/linux/task_work.h:22 [inline] + do_exit+0x9bb/0x1ae0 kernel/exit.c:865 + do_group_exit+0x149/0x400 kernel/exit.c:968 + SYSC_exit_group kernel/exit.c:979 [inline] + SyS_exit_group+0x1d/0x20 kernel/exit.c:977 + entry_SYSCALL_64_fastpath+0x1f/0x96 +RIP: 0033:0x44ad19 + +Fixes: 30f7ea1c2b5f ("packet: race condition in packet_bind") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: Francesco Ruggeri +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2976,6 +2976,10 @@ static int packet_do_bind(struct sock *s + if (need_rehook) { + if (po->running) { + rcu_read_unlock(); ++ /* prevents packet_notifier() from calling ++ * register_prot_hook() ++ */ ++ po->num = 0; + __unregister_prot_hook(sk, true); + rcu_read_lock(); + dev_curr = po->prot_hook.dev; +@@ -2984,6 +2988,7 @@ static int packet_do_bind(struct sock *s + dev->ifindex); + } + ++ BUG_ON(po->running); + po->num = proto; + po->prot_hook.type = proto; + diff --git a/queue-4.4/packet-fix-crash-in-fanout_demux_rollover.patch b/queue-4.4/packet-fix-crash-in-fanout_demux_rollover.patch new file mode 100644 index 00000000000..b3384eb4859 --- /dev/null +++ b/queue-4.4/packet-fix-crash-in-fanout_demux_rollover.patch @@ -0,0 +1,155 @@ +From foo@baz Thu Dec 14 18:55:00 CET 2017 +From: Mike Maloney +Date: Tue, 28 Nov 2017 10:44:29 -0500 +Subject: packet: fix crash in fanout_demux_rollover() + +From: Mike Maloney + + +syzkaller found a race condition fanout_demux_rollover() while removing +a packet socket from a fanout group. + +po->rollover is read and operated on during packet_rcv_fanout(), via +fanout_demux_rollover(), but the pointer is currently cleared before the +synchronization in packet_release(). It is safer to delay the cleanup +until after synchronize_net() has been called, ensuring all calls to +packet_rcv_fanout() for this socket have finished. + +To further simplify synchronization around the rollover structure, set +po->rollover in fanout_add() only if there are no errors. This removes +the need for rcu in the struct and in the call to +packet_getsockopt(..., PACKET_ROLLOVER_STATS, ...). + +Crashing stack trace: + fanout_demux_rollover+0xb6/0x4d0 net/packet/af_packet.c:1392 + packet_rcv_fanout+0x649/0x7c8 net/packet/af_packet.c:1487 + dev_queue_xmit_nit+0x835/0xc10 net/core/dev.c:1953 + xmit_one net/core/dev.c:2975 [inline] + dev_hard_start_xmit+0x16b/0xac0 net/core/dev.c:2995 + __dev_queue_xmit+0x17a4/0x2050 net/core/dev.c:3476 + dev_queue_xmit+0x17/0x20 net/core/dev.c:3509 + neigh_connected_output+0x489/0x720 net/core/neighbour.c:1379 + neigh_output include/net/neighbour.h:482 [inline] + ip6_finish_output2+0xad1/0x22a0 net/ipv6/ip6_output.c:120 + ip6_finish_output+0x2f9/0x920 net/ipv6/ip6_output.c:146 + NF_HOOK_COND include/linux/netfilter.h:239 [inline] + ip6_output+0x1f4/0x850 net/ipv6/ip6_output.c:163 + dst_output include/net/dst.h:459 [inline] + NF_HOOK.constprop.35+0xff/0x630 include/linux/netfilter.h:250 + mld_sendpack+0x6a8/0xcc0 net/ipv6/mcast.c:1660 + mld_send_initial_cr.part.24+0x103/0x150 net/ipv6/mcast.c:2072 + mld_send_initial_cr net/ipv6/mcast.c:2056 [inline] + ipv6_mc_dad_complete+0x99/0x130 net/ipv6/mcast.c:2079 + addrconf_dad_completed+0x595/0x970 net/ipv6/addrconf.c:4039 + addrconf_dad_work+0xac9/0x1160 net/ipv6/addrconf.c:3971 + process_one_work+0xbf0/0x1bc0 kernel/workqueue.c:2113 + worker_thread+0x223/0x1990 kernel/workqueue.c:2247 + kthread+0x35e/0x430 kernel/kthread.c:231 + ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:432 + +Fixes: 0648ab70afe6 ("packet: rollover prepare: per-socket state") +Fixes: 509c7a1ecc860 ("packet: avoid panic in packet_getsockopt()") +Reported-by: syzbot +Signed-off-by: Mike Maloney +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 32 ++++++++++---------------------- + net/packet/internal.h | 1 - + 2 files changed, 10 insertions(+), 23 deletions(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -1665,7 +1665,6 @@ static int fanout_add(struct sock *sk, u + atomic_long_set(&rollover->num, 0); + atomic_long_set(&rollover->num_huge, 0); + atomic_long_set(&rollover->num_failed, 0); +- po->rollover = rollover; + } + + match = NULL; +@@ -1710,6 +1709,8 @@ static int fanout_add(struct sock *sk, u + if (atomic_read(&match->sk_ref) < PACKET_FANOUT_MAX) { + __dev_remove_pack(&po->prot_hook); + po->fanout = match; ++ po->rollover = rollover; ++ rollover = NULL; + atomic_inc(&match->sk_ref); + __fanout_link(sk, po); + err = 0; +@@ -1723,10 +1724,7 @@ static int fanout_add(struct sock *sk, u + } + + out: +- if (err && rollover) { +- kfree_rcu(rollover, rcu); +- po->rollover = NULL; +- } ++ kfree(rollover); + mutex_unlock(&fanout_mutex); + return err; + } +@@ -1750,11 +1748,6 @@ static struct packet_fanout *fanout_rele + list_del(&f->list); + else + f = NULL; +- +- if (po->rollover) { +- kfree_rcu(po->rollover, rcu); +- po->rollover = NULL; +- } + } + mutex_unlock(&fanout_mutex); + +@@ -2914,6 +2907,7 @@ static int packet_release(struct socket + synchronize_net(); + + if (f) { ++ kfree(po->rollover); + fanout_release_data(f); + kfree(f); + } +@@ -3771,7 +3765,6 @@ static int packet_getsockopt(struct sock + void *data = &val; + union tpacket_stats_u st; + struct tpacket_rollover_stats rstats; +- struct packet_rollover *rollover; + + if (level != SOL_PACKET) + return -ENOPROTOOPT; +@@ -3850,18 +3843,13 @@ static int packet_getsockopt(struct sock + 0); + break; + case PACKET_ROLLOVER_STATS: +- rcu_read_lock(); +- rollover = rcu_dereference(po->rollover); +- if (rollover) { +- rstats.tp_all = atomic_long_read(&rollover->num); +- rstats.tp_huge = atomic_long_read(&rollover->num_huge); +- rstats.tp_failed = atomic_long_read(&rollover->num_failed); +- data = &rstats; +- lv = sizeof(rstats); +- } +- rcu_read_unlock(); +- if (!rollover) ++ if (!po->rollover) + return -EINVAL; ++ rstats.tp_all = atomic_long_read(&po->rollover->num); ++ rstats.tp_huge = atomic_long_read(&po->rollover->num_huge); ++ rstats.tp_failed = atomic_long_read(&po->rollover->num_failed); ++ data = &rstats; ++ lv = sizeof(rstats); + break; + case PACKET_TX_HAS_OFF: + val = po->tp_tx_has_off; +--- a/net/packet/internal.h ++++ b/net/packet/internal.h +@@ -92,7 +92,6 @@ struct packet_fanout { + + struct packet_rollover { + int sock; +- struct rcu_head rcu; + atomic_long_t num; + atomic_long_t num_huge; + atomic_long_t num_failed; diff --git a/queue-4.4/rds-fix-null-pointer-dereference-in-__rds_rdma_map.patch b/queue-4.4/rds-fix-null-pointer-dereference-in-__rds_rdma_map.patch new file mode 100644 index 00000000000..f2502f2ce54 --- /dev/null +++ b/queue-4.4/rds-fix-null-pointer-dereference-in-__rds_rdma_map.patch @@ -0,0 +1,89 @@ +From foo@baz Thu Dec 14 18:55:00 CET 2017 +From: Håkon Bugge +Date: Wed, 6 Dec 2017 17:18:28 +0100 +Subject: rds: Fix NULL pointer dereference in __rds_rdma_map + +From: Håkon Bugge + + +[ Upstream commit f3069c6d33f6ae63a1668737bc78aaaa51bff7ca ] + +This is a fix for syzkaller719569, where memory registration was +attempted without any underlying transport being loaded. + +Analysis of the case reveals that it is the setsockopt() RDS_GET_MR +(2) and RDS_GET_MR_FOR_DEST (7) that are vulnerable. + +Here is an example stack trace when the bug is hit: + +BUG: unable to handle kernel NULL pointer dereference at 00000000000000c0 +IP: __rds_rdma_map+0x36/0x440 [rds] +PGD 2f93d03067 P4D 2f93d03067 PUD 2f93d02067 PMD 0 +Oops: 0000 [#1] SMP +Modules linked in: bridge stp llc tun rpcsec_gss_krb5 nfsv4 +dns_resolver nfs fscache rds binfmt_misc sb_edac intel_powerclamp +coretemp kvm_intel kvm irqbypass crct10dif_pclmul c rc32_pclmul +ghash_clmulni_intel pcbc aesni_intel crypto_simd glue_helper cryptd +iTCO_wdt mei_me sg iTCO_vendor_support ipmi_si mei ipmi_devintf nfsd +shpchp pcspkr i2c_i801 ioatd ma ipmi_msghandler wmi lpc_ich mfd_core +auth_rpcgss nfs_acl lockd grace sunrpc ip_tables ext4 mbcache jbd2 +mgag200 i2c_algo_bit drm_kms_helper ixgbe syscopyarea ahci sysfillrect +sysimgblt libahci mdio fb_sys_fops ttm ptp libata sd_mod mlx4_core drm +crc32c_intel pps_core megaraid_sas i2c_core dca dm_mirror +dm_region_hash dm_log dm_mod +CPU: 48 PID: 45787 Comm: repro_set2 Not tainted 4.14.2-3.el7uek.x86_64 #2 +Hardware name: Oracle Corporation ORACLE SERVER X5-2L/ASM,MOBO TRAY,2U, BIOS 31110000 03/03/2017 +task: ffff882f9190db00 task.stack: ffffc9002b994000 +RIP: 0010:__rds_rdma_map+0x36/0x440 [rds] +RSP: 0018:ffffc9002b997df0 EFLAGS: 00010202 +RAX: 0000000000000000 RBX: ffff882fa2182580 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: ffffc9002b997e40 RDI: ffff882fa2182580 +RBP: ffffc9002b997e30 R08: 0000000000000000 R09: 0000000000000002 +R10: ffff885fb29e3838 R11: 0000000000000000 R12: ffff882fa2182580 +R13: ffff882fa2182580 R14: 0000000000000002 R15: 0000000020000ffc +FS: 00007fbffa20b700(0000) GS:ffff882fbfb80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000000000c0 CR3: 0000002f98a66006 CR4: 00000000001606e0 +Call Trace: + rds_get_mr+0x56/0x80 [rds] + rds_setsockopt+0x172/0x340 [rds] + ? __fget_light+0x25/0x60 + ? __fdget+0x13/0x20 + SyS_setsockopt+0x80/0xe0 + do_syscall_64+0x67/0x1b0 + entry_SYSCALL64_slow_path+0x25/0x25 +RIP: 0033:0x7fbff9b117f9 +RSP: 002b:00007fbffa20aed8 EFLAGS: 00000293 ORIG_RAX: 0000000000000036 +RAX: ffffffffffffffda RBX: 00000000000c84a4 RCX: 00007fbff9b117f9 +RDX: 0000000000000002 RSI: 0000400000000114 RDI: 000000000000109b +RBP: 00007fbffa20af10 R08: 0000000000000020 R09: 00007fbff9dd7860 +R10: 0000000020000ffc R11: 0000000000000293 R12: 0000000000000000 +R13: 00007fbffa20b9c0 R14: 00007fbffa20b700 R15: 0000000000000021 + +Code: 41 56 41 55 49 89 fd 41 54 53 48 83 ec 18 8b 87 f0 02 00 00 48 +89 55 d0 48 89 4d c8 85 c0 0f 84 2d 03 00 00 48 8b 87 00 03 00 00 <48> +83 b8 c0 00 00 00 00 0f 84 25 03 00 0 0 48 8b 06 48 8b 56 08 + +The fix is to check the existence of an underlying transport in +__rds_rdma_map(). + +Signed-off-by: HÃ¥kon Bugge +Reported-by: syzbot +Acked-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rds/rdma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/rds/rdma.c ++++ b/net/rds/rdma.c +@@ -184,7 +184,7 @@ static int __rds_rdma_map(struct rds_soc + long i; + int ret; + +- if (rs->rs_bound_addr == 0) { ++ if (rs->rs_bound_addr == 0 || !rs->rs_transport) { + ret = -ENOTCONN; /* XXX not a great errno */ + goto out; + } diff --git a/queue-4.4/series b/queue-4.4/series index 12ab41e2bdf..5da606e9134 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -95,3 +95,8 @@ audit-ensure-that-audit-1-actually-enables-audit-for-pid-1.patch ipmi-stop-timers-before-cleaning-up-the-module.patch s390-always-save-and-restore-all-registers-on-context-switch.patch more-bio_map_user_iov-leak-fixes.patch +tipc-fix-memory-leak-in-tipc_accept_from_sock.patch +rds-fix-null-pointer-dereference-in-__rds_rdma_map.patch +sit-update-frag_off-info.patch +packet-fix-crash-in-fanout_demux_rollover.patch +net-packet-fix-a-race-in-packet_bind-and-packet_notifier.patch diff --git a/queue-4.4/sit-update-frag_off-info.patch b/queue-4.4/sit-update-frag_off-info.patch new file mode 100644 index 00000000000..31a47c01e66 --- /dev/null +++ b/queue-4.4/sit-update-frag_off-info.patch @@ -0,0 +1,32 @@ +From foo@baz Thu Dec 14 18:55:00 CET 2017 +From: Hangbin Liu +Date: Thu, 30 Nov 2017 10:41:14 +0800 +Subject: sit: update frag_off info + +From: Hangbin Liu + + +[ Upstream commit f859b4af1c52493ec21173ccc73d0b60029b5b88 ] + +After parsing the sit netlink change info, we forget to update frag_off in +ipip6_tunnel_update(). Fix it by assigning frag_off with new value. + +Reported-by: Jianlin Shi +Signed-off-by: Hangbin Liu +Acked-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/sit.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1093,6 +1093,7 @@ static void ipip6_tunnel_update(struct i + ipip6_tunnel_link(sitn, t); + t->parms.iph.ttl = p->iph.ttl; + t->parms.iph.tos = p->iph.tos; ++ t->parms.iph.frag_off = p->iph.frag_off; + if (t->parms.link != p->link) { + t->parms.link = p->link; + ipip6_tunnel_bind_dev(t->dev); diff --git a/queue-4.4/tipc-fix-memory-leak-in-tipc_accept_from_sock.patch b/queue-4.4/tipc-fix-memory-leak-in-tipc_accept_from_sock.patch new file mode 100644 index 00000000000..05139d7aa28 --- /dev/null +++ b/queue-4.4/tipc-fix-memory-leak-in-tipc_accept_from_sock.patch @@ -0,0 +1,34 @@ +From foo@baz Thu Dec 14 18:55:00 CET 2017 +From: Jon Maloy +Date: Mon, 4 Dec 2017 22:00:20 +0100 +Subject: tipc: fix memory leak in tipc_accept_from_sock() + +From: Jon Maloy + + +[ Upstream commit a7d5f107b4978e08eeab599ee7449af34d034053 ] + +When the function tipc_accept_from_sock() fails to create an instance of +struct tipc_subscriber it omits to free the already created instance of +struct tipc_conn instance before it returns. + +We fix that with this commit. + +Reported-by: David S. Miller +Signed-off-by: Jon Maloy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/server.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/tipc/server.c ++++ b/net/tipc/server.c +@@ -311,6 +311,7 @@ static int tipc_accept_from_sock(struct + newcon->usr_data = s->tipc_conn_new(newcon->conid); + if (!newcon->usr_data) { + sock_release(newsock); ++ conn_put(newcon); + return -ENOMEM; + } +