]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Dec 2017 17:55:26 +0000 (18:55 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Dec 2017 17:55:26 +0000 (18:55 +0100)
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

queue-4.4/net-packet-fix-a-race-in-packet_bind-and-packet_notifier.patch [new file with mode: 0644]
queue-4.4/packet-fix-crash-in-fanout_demux_rollover.patch [new file with mode: 0644]
queue-4.4/rds-fix-null-pointer-dereference-in-__rds_rdma_map.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/sit-update-frag_off-info.patch [new file with mode: 0644]
queue-4.4/tipc-fix-memory-leak-in-tipc_accept_from_sock.patch [new file with mode: 0644]

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 (file)
index 0000000..1cebc2a
--- /dev/null
@@ -0,0 +1,93 @@
+From foo@baz Thu Dec 14 18:55:00 CET 2017
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 28 Nov 2017 08:03:30 -0800
+Subject: net/packet: fix a race in packet_bind() and packet_notifier()
+
+From: Eric Dumazet <edumazet@google.com>
+
+
+[ 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 <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: Francesco Ruggeri <fruggeri@aristanetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..b3384eb
--- /dev/null
@@ -0,0 +1,155 @@
+From foo@baz Thu Dec 14 18:55:00 CET 2017
+From: Mike Maloney <maloney@google.com>
+Date: Tue, 28 Nov 2017 10:44:29 -0500
+Subject: packet: fix crash in fanout_demux_rollover()
+
+From: Mike Maloney <maloney@google.com>
+
+
+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 <syzkaller@googlegroups.com>
+Signed-off-by: Mike Maloney <maloney@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f2502f2
--- /dev/null
@@ -0,0 +1,89 @@
+From foo@baz Thu Dec 14 18:55:00 CET 2017
+From: Håkon Bugge <Haakon.Bugge@oracle.com>
+Date: Wed, 6 Dec 2017 17:18:28 +0100
+Subject: rds: Fix NULL pointer dereference in __rds_rdma_map
+
+From: Håkon Bugge <Haakon.Bugge@oracle.com>
+
+
+[ 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 <haakon.bugge@oracle.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+       }
index 12ab41e2bdf27ba91d5912fc82a3666b6c0657ba..5da606e91341e0e273ca8c2cf1b0529368184d22 100644 (file)
@@ -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 (file)
index 0000000..31a47c0
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Thu Dec 14 18:55:00 CET 2017
+From: Hangbin Liu <liuhangbin@gmail.com>
+Date: Thu, 30 Nov 2017 10:41:14 +0800
+Subject: sit: update frag_off info
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+
+[ 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 <jishi@redhat.com>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..05139d7
--- /dev/null
@@ -0,0 +1,34 @@
+From foo@baz Thu Dec 14 18:55:00 CET 2017
+From: Jon Maloy <jon.maloy@ericsson.com>
+Date: Mon, 4 Dec 2017 22:00:20 +0100
+Subject: tipc: fix memory leak in tipc_accept_from_sock()
+
+From: Jon Maloy <jon.maloy@ericsson.com>
+
+
+[ 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 <davem@davemloft.net>
+Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+       }