]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 May 2017 19:43:07 +0000 (12:43 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 May 2017 19:43:07 +0000 (12:43 -0700)
added patches:
l2tp-fix-racy-sock_zapped-flag-check-in-l2tp_ip-6-_bind.patch
mm-avoid-setting-up-anonymous-pages-into-file-mapping.patch
net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch
perf-tighten-and-fix-the-grouping-condition.patch
posix_acl-clear-sgid-bit-when-setting-file-permissions.patch
regulator-core-fix-regualtor_ena_gpio_free-not-to-access-pin-after-freeing.patch

queue-3.18/l2tp-fix-racy-sock_zapped-flag-check-in-l2tp_ip-6-_bind.patch [new file with mode: 0644]
queue-3.18/mm-avoid-setting-up-anonymous-pages-into-file-mapping.patch [new file with mode: 0644]
queue-3.18/net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch [new file with mode: 0644]
queue-3.18/perf-tighten-and-fix-the-grouping-condition.patch [new file with mode: 0644]
queue-3.18/posix_acl-clear-sgid-bit-when-setting-file-permissions.patch [new file with mode: 0644]
queue-3.18/regulator-core-fix-regualtor_ena_gpio_free-not-to-access-pin-after-freeing.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/l2tp-fix-racy-sock_zapped-flag-check-in-l2tp_ip-6-_bind.patch b/queue-3.18/l2tp-fix-racy-sock_zapped-flag-check-in-l2tp_ip-6-_bind.patch
new file mode 100644 (file)
index 0000000..e6daed8
--- /dev/null
@@ -0,0 +1,167 @@
+From 32c231164b762dddefa13af5a0101032c70b50ef Mon Sep 17 00:00:00 2001
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Fri, 18 Nov 2016 22:13:00 +0100
+Subject: l2tp: fix racy SOCK_ZAPPED flag check in l2tp_ip{,6}_bind()
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+commit 32c231164b762dddefa13af5a0101032c70b50ef upstream.
+
+Lock socket before checking the SOCK_ZAPPED flag in l2tp_ip6_bind().
+Without lock, a concurrent call could modify the socket flags between
+the sock_flag(sk, SOCK_ZAPPED) test and the lock_sock() call. This way,
+a socket could be inserted twice in l2tp_ip6_bind_table. Releasing it
+would then leave a stale pointer there, generating use-after-free
+errors when walking through the list or modifying adjacent entries.
+
+BUG: KASAN: use-after-free in l2tp_ip6_close+0x22e/0x290 at addr ffff8800081b0ed8
+Write of size 8 by task syz-executor/10987
+CPU: 0 PID: 10987 Comm: syz-executor Not tainted 4.8.0+ #39
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
+ ffff880031d97838 ffffffff829f835b ffff88001b5a1640 ffff8800081b0ec0
+ ffff8800081b15a0 ffff8800081b6d20 ffff880031d97860 ffffffff8174d3cc
+ ffff880031d978f0 ffff8800081b0e80 ffff88001b5a1640 ffff880031d978e0
+Call Trace:
+ [<ffffffff829f835b>] dump_stack+0xb3/0x118 lib/dump_stack.c:15
+ [<ffffffff8174d3cc>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
+ [<     inline     >] print_address_description mm/kasan/report.c:194
+ [<ffffffff8174d666>] kasan_report_error+0x1f6/0x4d0 mm/kasan/report.c:283
+ [<     inline     >] kasan_report mm/kasan/report.c:303
+ [<ffffffff8174db7e>] __asan_report_store8_noabort+0x3e/0x40 mm/kasan/report.c:329
+ [<     inline     >] __write_once_size ./include/linux/compiler.h:249
+ [<     inline     >] __hlist_del ./include/linux/list.h:622
+ [<     inline     >] hlist_del_init ./include/linux/list.h:637
+ [<ffffffff8579047e>] l2tp_ip6_close+0x22e/0x290 net/l2tp/l2tp_ip6.c:239
+ [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415
+ [<ffffffff851dc5a0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
+ [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 net/socket.c:570
+ [<ffffffff84c45976>] sock_close+0x16/0x20 net/socket.c:1017
+ [<ffffffff817a108c>] __fput+0x28c/0x780 fs/file_table.c:208
+ [<ffffffff817a1605>] ____fput+0x15/0x20 fs/file_table.c:244
+ [<ffffffff813774f9>] task_work_run+0xf9/0x170
+ [<ffffffff81324aae>] do_exit+0x85e/0x2a00
+ [<ffffffff81326dc8>] do_group_exit+0x108/0x330
+ [<ffffffff81348cf7>] get_signal+0x617/0x17a0 kernel/signal.c:2307
+ [<ffffffff811b49af>] do_signal+0x7f/0x18f0
+ [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156
+ [<     inline     >] prepare_exit_to_usermode arch/x86/entry/common.c:190
+ [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259
+ [<ffffffff85e4d726>] entry_SYSCALL_64_fastpath+0xc4/0xc6
+Object at ffff8800081b0ec0, in cache L2TP/IPv6 size: 1448
+Allocated:
+PID = 10987
+ [ 1116.897025] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
+ [ 1116.897025] [<ffffffff8174c736>] save_stack+0x46/0xd0
+ [ 1116.897025] [<ffffffff8174c9ad>] kasan_kmalloc+0xad/0xe0
+ [ 1116.897025] [<ffffffff8174cee2>] kasan_slab_alloc+0x12/0x20
+ [ 1116.897025] [<     inline     >] slab_post_alloc_hook mm/slab.h:417
+ [ 1116.897025] [<     inline     >] slab_alloc_node mm/slub.c:2708
+ [ 1116.897025] [<     inline     >] slab_alloc mm/slub.c:2716
+ [ 1116.897025] [<ffffffff817476a8>] kmem_cache_alloc+0xc8/0x2b0 mm/slub.c:2721
+ [ 1116.897025] [<ffffffff84c4f6a9>] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1326
+ [ 1116.897025] [<ffffffff84c58ac8>] sk_alloc+0x38/0xae0 net/core/sock.c:1388
+ [ 1116.897025] [<ffffffff851ddf67>] inet6_create+0x2d7/0x1000 net/ipv6/af_inet6.c:182
+ [ 1116.897025] [<ffffffff84c4af7b>] __sock_create+0x37b/0x640 net/socket.c:1153
+ [ 1116.897025] [<     inline     >] sock_create net/socket.c:1193
+ [ 1116.897025] [<     inline     >] SYSC_socket net/socket.c:1223
+ [ 1116.897025] [<ffffffff84c4b46f>] SyS_socket+0xef/0x1b0 net/socket.c:1203
+ [ 1116.897025] [<ffffffff85e4d685>] entry_SYSCALL_64_fastpath+0x23/0xc6
+Freed:
+PID = 10987
+ [ 1116.897025] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
+ [ 1116.897025] [<ffffffff8174c736>] save_stack+0x46/0xd0
+ [ 1116.897025] [<ffffffff8174cf61>] kasan_slab_free+0x71/0xb0
+ [ 1116.897025] [<     inline     >] slab_free_hook mm/slub.c:1352
+ [ 1116.897025] [<     inline     >] slab_free_freelist_hook mm/slub.c:1374
+ [ 1116.897025] [<     inline     >] slab_free mm/slub.c:2951
+ [ 1116.897025] [<ffffffff81748b28>] kmem_cache_free+0xc8/0x330 mm/slub.c:2973
+ [ 1116.897025] [<     inline     >] sk_prot_free net/core/sock.c:1369
+ [ 1116.897025] [<ffffffff84c541eb>] __sk_destruct+0x32b/0x4f0 net/core/sock.c:1444
+ [ 1116.897025] [<ffffffff84c5aca4>] sk_destruct+0x44/0x80 net/core/sock.c:1452
+ [ 1116.897025] [<ffffffff84c5ad33>] __sk_free+0x53/0x220 net/core/sock.c:1460
+ [ 1116.897025] [<ffffffff84c5af23>] sk_free+0x23/0x30 net/core/sock.c:1471
+ [ 1116.897025] [<ffffffff84c5cb6c>] sk_common_release+0x28c/0x3e0 ./include/net/sock.h:1589
+ [ 1116.897025] [<ffffffff8579044e>] l2tp_ip6_close+0x1fe/0x290 net/l2tp/l2tp_ip6.c:243
+ [ 1116.897025] [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415
+ [ 1116.897025] [<ffffffff851dc5a0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
+ [ 1116.897025] [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 net/socket.c:570
+ [ 1116.897025] [<ffffffff84c45976>] sock_close+0x16/0x20 net/socket.c:1017
+ [ 1116.897025] [<ffffffff817a108c>] __fput+0x28c/0x780 fs/file_table.c:208
+ [ 1116.897025] [<ffffffff817a1605>] ____fput+0x15/0x20 fs/file_table.c:244
+ [ 1116.897025] [<ffffffff813774f9>] task_work_run+0xf9/0x170
+ [ 1116.897025] [<ffffffff81324aae>] do_exit+0x85e/0x2a00
+ [ 1116.897025] [<ffffffff81326dc8>] do_group_exit+0x108/0x330
+ [ 1116.897025] [<ffffffff81348cf7>] get_signal+0x617/0x17a0 kernel/signal.c:2307
+ [ 1116.897025] [<ffffffff811b49af>] do_signal+0x7f/0x18f0
+ [ 1116.897025] [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156
+ [ 1116.897025] [<     inline     >] prepare_exit_to_usermode arch/x86/entry/common.c:190
+ [ 1116.897025] [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259
+ [ 1116.897025] [<ffffffff85e4d726>] entry_SYSCALL_64_fastpath+0xc4/0xc6
+Memory state around the buggy address:
+ ffff8800081b0d80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff8800081b0e00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+>ffff8800081b0e80: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
+                                                    ^
+ ffff8800081b0f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff8800081b0f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+==================================================================
+
+The same issue exists with l2tp_ip_bind() and l2tp_ip_bind_table.
+
+Fixes: c51ce49735c1 ("l2tp: fix oops in L2TP IP sockets for connect() AF_UNSPEC case")
+Reported-by: Baozeng Ding <sploving1@gmail.com>
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Tested-by: Baozeng Ding <sploving1@gmail.com>
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/l2tp/l2tp_ip.c  |    5 +++--
+ net/l2tp/l2tp_ip6.c |    5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/net/l2tp/l2tp_ip.c
++++ b/net/l2tp/l2tp_ip.c
+@@ -252,8 +252,6 @@ static int l2tp_ip_bind(struct sock *sk,
+       int ret;
+       int chk_addr_ret;
+-      if (!sock_flag(sk, SOCK_ZAPPED))
+-              return -EINVAL;
+       if (addr_len < sizeof(struct sockaddr_l2tpip))
+               return -EINVAL;
+       if (addr->l2tp_family != AF_INET)
+@@ -268,6 +266,9 @@ static int l2tp_ip_bind(struct sock *sk,
+       read_unlock_bh(&l2tp_ip_lock);
+       lock_sock(sk);
++      if (!sock_flag(sk, SOCK_ZAPPED))
++              goto out;
++
+       if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip))
+               goto out;
+--- a/net/l2tp/l2tp_ip6.c
++++ b/net/l2tp/l2tp_ip6.c
+@@ -266,8 +266,6 @@ static int l2tp_ip6_bind(struct sock *sk
+       int addr_type;
+       int err;
+-      if (!sock_flag(sk, SOCK_ZAPPED))
+-              return -EINVAL;
+       if (addr->l2tp_family != AF_INET6)
+               return -EINVAL;
+       if (addr_len < sizeof(*addr))
+@@ -293,6 +291,9 @@ static int l2tp_ip6_bind(struct sock *sk
+       lock_sock(sk);
+       err = -EINVAL;
++      if (!sock_flag(sk, SOCK_ZAPPED))
++              goto out_unlock;
++
+       if (sk->sk_state != TCP_CLOSE)
+               goto out_unlock;
diff --git a/queue-3.18/mm-avoid-setting-up-anonymous-pages-into-file-mapping.patch b/queue-3.18/mm-avoid-setting-up-anonymous-pages-into-file-mapping.patch
new file mode 100644 (file)
index 0000000..89a0b24
--- /dev/null
@@ -0,0 +1,71 @@
+From 6b7339f4c31ad69c8e9c0b2859276e22cf72176d Mon Sep 17 00:00:00 2001
+From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Date: Mon, 6 Jul 2015 23:18:37 +0300
+Subject: mm: avoid setting up anonymous pages into file mapping
+
+From: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+
+commit 6b7339f4c31ad69c8e9c0b2859276e22cf72176d upstream.
+
+Reading page fault handler code I've noticed that under right
+circumstances kernel would map anonymous pages into file mappings: if
+the VMA doesn't have vm_ops->fault() and the VMA wasn't fully populated
+on ->mmap(), kernel would handle page fault to not populated pte with
+do_anonymous_page().
+
+Let's change page fault handler to use do_anonymous_page() only on
+anonymous VMA (->vm_ops == NULL) and make sure that the VMA is not
+shared.
+
+For file mappings without vm_ops->fault() or shred VMA without vm_ops,
+page fault on pte_none() entry would lead to SIGBUS.
+
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memory.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2629,6 +2629,10 @@ static int do_anonymous_page(struct mm_s
+       pte_unmap(page_table);
++      /* File mapping without ->vm_ops ? */
++      if (vma->vm_flags & VM_SHARED)
++              return VM_FAULT_SIGBUS;
++
+       /* Check if we need to add a guard page to the stack */
+       if (check_stack_guard_page(vma, address) < 0)
+               return VM_FAULT_SIGSEGV;
+@@ -3033,6 +3037,9 @@ static int do_linear_fault(struct mm_str
+                       - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+       pte_unmap(page_table);
++      /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
++      if (!vma->vm_ops->fault)
++              return VM_FAULT_SIGBUS;
+       if (!(flags & FAULT_FLAG_WRITE))
+               return do_read_fault(mm, vma, address, pmd, pgoff, flags,
+                               orig_pte);
+@@ -3198,11 +3205,9 @@ static int handle_pte_fault(struct mm_st
+       entry = ACCESS_ONCE(*pte);
+       if (!pte_present(entry)) {
+               if (pte_none(entry)) {
+-                      if (vma->vm_ops) {
+-                              if (likely(vma->vm_ops->fault))
+-                                      return do_linear_fault(mm, vma, address,
++                      if (vma->vm_ops)
++                              return do_linear_fault(mm, vma, address,
+                                               pte, pmd, flags, entry);
+-                      }
+                       return do_anonymous_page(mm, vma, address,
+                                                pte, pmd, flags);
+               }
diff --git a/queue-3.18/net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch b/queue-3.18/net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch
new file mode 100644 (file)
index 0000000..764c9fd
--- /dev/null
@@ -0,0 +1,51 @@
+From b98b0bc8c431e3ceb4b26b0dfc8db509518fb290 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 2 Dec 2016 09:44:53 -0800
+Subject: net: avoid signed overflows for SO_{SND|RCV}BUFFORCE
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit b98b0bc8c431e3ceb4b26b0dfc8db509518fb290 upstream.
+
+CAP_NET_ADMIN users should not be allowed to set negative
+sk_sndbuf or sk_rcvbuf values, as it can lead to various memory
+corruptions, crashes, OOM...
+
+Note that before commit 82981930125a ("net: cleanups in
+sock_setsockopt()"), the bug was even more serious, since SO_SNDBUF
+and SO_RCVBUF were vulnerable.
+
+This needs to be backported to all known linux kernels.
+
+Again, many thanks to syzkaller team for discovering this gem.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/sock.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -733,7 +733,7 @@ int sock_setsockopt(struct socket *sock,
+               val = min_t(u32, val, sysctl_wmem_max);
+ set_sndbuf:
+               sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
+-              sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
++              sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
+               /* Wake up sending tasks if we upped the value. */
+               sk->sk_write_space(sk);
+               break;
+@@ -769,7 +769,7 @@ set_rcvbuf:
+                * returning the value we actually used in getsockopt
+                * is the most desirable behavior.
+                */
+-              sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
++              sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
+               break;
+       case SO_RCVBUFFORCE:
diff --git a/queue-3.18/perf-tighten-and-fix-the-grouping-condition.patch b/queue-3.18/perf-tighten-and-fix-the-grouping-condition.patch
new file mode 100644 (file)
index 0000000..34054d9
--- /dev/null
@@ -0,0 +1,91 @@
+From c3c87e770458aa004bd7ed3f29945ff436fd6511 Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Fri, 23 Jan 2015 11:19:48 +0100
+Subject: perf: Tighten (and fix) the grouping condition
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit c3c87e770458aa004bd7ed3f29945ff436fd6511 upstream.
+
+The fix from 9fc81d87420d ("perf: Fix events installation during
+moving group") was incomplete in that it failed to recognise that
+creating a group with events for different CPUs is semantically
+broken -- they cannot be co-scheduled.
+
+Furthermore, it leads to real breakage where, when we create an event
+for CPU Y and then migrate it to form a group on CPU X, the code gets
+confused where the counter is programmed -- triggered in practice
+as well by me via the perf fuzzer.
+
+Fix this by tightening the rules for creating groups. Only allow
+grouping of counters that can be co-scheduled in the same context.
+This means for the same task and/or the same cpu.
+
+Fixes: 9fc81d87420d ("perf: Fix events installation during moving group")
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: http://lkml.kernel.org/r/20150123125834.090683288@infradead.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/perf_event.h |    6 ------
+ kernel/events/core.c       |   15 +++++++++++++--
+ 2 files changed, 13 insertions(+), 8 deletions(-)
+
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -455,11 +455,6 @@ struct perf_event {
+ #endif /* CONFIG_PERF_EVENTS */
+ };
+-enum perf_event_context_type {
+-      task_context,
+-      cpu_context,
+-};
+-
+ /**
+  * struct perf_event_context - event context structure
+  *
+@@ -467,7 +462,6 @@ enum perf_event_context_type {
+  */
+ struct perf_event_context {
+       struct pmu                      *pmu;
+-      enum perf_event_context_type    type;
+       /*
+        * Protect the states of the events in the list,
+        * nr_active, and the list:
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -6803,7 +6803,6 @@ skip_type:
+               __perf_event_init_context(&cpuctx->ctx);
+               lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex);
+               lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock);
+-              cpuctx->ctx.type = cpu_context;
+               cpuctx->ctx.pmu = pmu;
+               __perf_cpu_hrtimer_init(cpuctx, cpu);
+@@ -7445,7 +7444,19 @@ SYSCALL_DEFINE5(perf_event_open,
+                * task or CPU context:
+                */
+               if (move_group) {
+-                      if (group_leader->ctx->type != ctx->type)
++                      /*
++                       * Make sure we're both on the same task, or both
++                       * per-cpu events.
++                       */
++                      if (group_leader->ctx->task != ctx->task)
++                              goto err_context;
++
++                      /*
++                       * Make sure we're both events for the same CPU;
++                       * grouping events for different CPUs is broken; since
++                       * you can never concurrently schedule them anyhow.
++                       */
++                      if (group_leader->cpu != event->cpu)
+                               goto err_context;
+               } else {
+                       if (group_leader->ctx != ctx)
diff --git a/queue-3.18/posix_acl-clear-sgid-bit-when-setting-file-permissions.patch b/queue-3.18/posix_acl-clear-sgid-bit-when-setting-file-permissions.patch
new file mode 100644 (file)
index 0000000..9ec056d
--- /dev/null
@@ -0,0 +1,386 @@
+From 073931017b49d9458aa351605b43a7e34598caef Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 19 Sep 2016 17:39:09 +0200
+Subject: posix_acl: Clear SGID bit when setting file permissions
+
+From: Jan Kara <jack@suse.cz>
+
+commit 073931017b49d9458aa351605b43a7e34598caef upstream.
+
+When file permissions are modified via chmod(2) and the user is not in
+the owning group or capable of CAP_FSETID, the setgid bit is cleared in
+inode_change_ok().  Setting a POSIX ACL via setxattr(2) sets the file
+permissions as well as the new ACL, but doesn't clear the setgid bit in
+a similar way; this allows to bypass the check in chmod(2).  Fix that.
+
+References: CVE-2016-7097
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/9p/acl.c               |   40 +++++++++++++++++-----------------------
+ fs/btrfs/acl.c            |    6 ++----
+ fs/ceph/acl.c             |    6 ++----
+ fs/ext2/acl.c             |   12 ++++--------
+ fs/ext4/acl.c             |   12 ++++--------
+ fs/f2fs/acl.c             |    6 ++----
+ fs/gfs2/acl.c             |   12 +++---------
+ fs/hfsplus/posix_acl.c    |    4 ++--
+ fs/jffs2/acl.c            |    9 ++++-----
+ fs/jfs/acl.c              |    6 ++----
+ fs/ocfs2/acl.c            |   20 ++++++++------------
+ fs/posix_acl.c            |   31 +++++++++++++++++++++++++++++++
+ fs/reiserfs/xattr_acl.c   |    8 ++------
+ fs/xfs/xfs_acl.c          |   13 ++++---------
+ include/linux/posix_acl.h |    1 +
+ 15 files changed, 88 insertions(+), 98 deletions(-)
+
+--- a/fs/9p/acl.c
++++ b/fs/9p/acl.c
+@@ -320,32 +320,26 @@ static int v9fs_xattr_set_acl(struct den
+       case ACL_TYPE_ACCESS:
+               name = POSIX_ACL_XATTR_ACCESS;
+               if (acl) {
+-                      umode_t mode = inode->i_mode;
+-                      retval = posix_acl_equiv_mode(acl, &mode);
+-                      if (retval < 0)
++                      struct iattr iattr;
++
++                      retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
++                      if (retval)
+                               goto err_out;
+-                      else {
+-                              struct iattr iattr;
+-                              if (retval == 0) {
+-                                      /*
+-                                       * ACL can be represented
+-                                       * by the mode bits. So don't
+-                                       * update ACL.
+-                                       */
+-                                      acl = NULL;
+-                                      value = NULL;
+-                                      size = 0;
+-                              }
+-                              /* Updte the mode bits */
+-                              iattr.ia_mode = ((mode & S_IALLUGO) |
+-                                               (inode->i_mode & ~S_IALLUGO));
+-                              iattr.ia_valid = ATTR_MODE;
+-                              /* FIXME should we update ctime ?
+-                               * What is the following setxattr update the
+-                               * mode ?
++                      if (!acl) {
++                              /*
++                               * ACL can be represented
++                               * by the mode bits. So don't
++                               * update ACL.
+                                */
+-                              v9fs_vfs_setattr_dotl(dentry, &iattr);
++                              value = NULL;
++                              size = 0;
+                       }
++                      iattr.ia_valid = ATTR_MODE;
++                      /* FIXME should we update ctime ?
++                       * What is the following setxattr update the
++                       * mode ?
++                       */
++                      v9fs_vfs_setattr_dotl(dentry, &iattr);
+               }
+               break;
+       case ACL_TYPE_DEFAULT:
+--- a/fs/btrfs/acl.c
++++ b/fs/btrfs/acl.c
+@@ -83,11 +83,9 @@ static int __btrfs_set_acl(struct btrfs_
+       case ACL_TYPE_ACCESS:
+               name = POSIX_ACL_XATTR_ACCESS;
+               if (acl) {
+-                      ret = posix_acl_equiv_mode(acl, &inode->i_mode);
+-                      if (ret < 0)
++                      ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++                      if (ret)
+                               return ret;
+-                      if (ret == 0)
+-                              acl = NULL;
+               }
+               ret = 0;
+               break;
+--- a/fs/ceph/acl.c
++++ b/fs/ceph/acl.c
+@@ -108,11 +108,9 @@ int ceph_set_acl(struct inode *inode, st
+       case ACL_TYPE_ACCESS:
+               name = POSIX_ACL_XATTR_ACCESS;
+               if (acl) {
+-                      ret = posix_acl_equiv_mode(acl, &new_mode);
+-                      if (ret < 0)
++                      ret = posix_acl_update_mode(inode, &new_mode, &acl);
++                      if (ret)
+                               goto out;
+-                      if (ret == 0)
+-                              acl = NULL;
+               }
+               break;
+       case ACL_TYPE_DEFAULT:
+--- a/fs/ext2/acl.c
++++ b/fs/ext2/acl.c
+@@ -193,15 +193,11 @@ ext2_set_acl(struct inode *inode, struct
+               case ACL_TYPE_ACCESS:
+                       name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
+                       if (acl) {
+-                              error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-                              if (error < 0)
++                              error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++                              if (error)
+                                       return error;
+-                              else {
+-                                      inode->i_ctime = CURRENT_TIME_SEC;
+-                                      mark_inode_dirty(inode);
+-                                      if (error == 0)
+-                                              acl = NULL;
+-                              }
++                              inode->i_ctime = CURRENT_TIME_SEC;
++                              mark_inode_dirty(inode);
+                       }
+                       break;
+--- a/fs/ext4/acl.c
++++ b/fs/ext4/acl.c
+@@ -201,15 +201,11 @@ __ext4_set_acl(handle_t *handle, struct
+       case ACL_TYPE_ACCESS:
+               name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
+               if (acl) {
+-                      error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-                      if (error < 0)
++                      error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++                      if (error)
+                               return error;
+-                      else {
+-                              inode->i_ctime = ext4_current_time(inode);
+-                              ext4_mark_inode_dirty(handle, inode);
+-                              if (error == 0)
+-                                      acl = NULL;
+-                      }
++                      inode->i_ctime = ext4_current_time(inode);
++                      ext4_mark_inode_dirty(handle, inode);
+               }
+               break;
+--- a/fs/f2fs/acl.c
++++ b/fs/f2fs/acl.c
+@@ -207,12 +207,10 @@ static int __f2fs_set_acl(struct inode *
+       case ACL_TYPE_ACCESS:
+               name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
+               if (acl) {
+-                      error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-                      if (error < 0)
++                      error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++                      if (error)
+                               return error;
+                       set_acl_inode(fi, inode->i_mode);
+-                      if (error == 0)
+-                              acl = NULL;
+               }
+               break;
+--- a/fs/gfs2/acl.c
++++ b/fs/gfs2/acl.c
+@@ -79,17 +79,11 @@ int gfs2_set_acl(struct inode *inode, st
+       if (type == ACL_TYPE_ACCESS) {
+               umode_t mode = inode->i_mode;
+-              error = posix_acl_equiv_mode(acl, &mode);
+-              if (error < 0)
++              error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++              if (error)
+                       return error;
+-
+-              if (error == 0)
+-                      acl = NULL;
+-
+-              if (mode != inode->i_mode) {
+-                      inode->i_mode = mode;
++              if (mode != inode->i_mode)
+                       mark_inode_dirty(inode);
+-              }
+       }
+       if (acl) {
+--- a/fs/hfsplus/posix_acl.c
++++ b/fs/hfsplus/posix_acl.c
+@@ -68,8 +68,8 @@ int hfsplus_set_posix_acl(struct inode *
+       case ACL_TYPE_ACCESS:
+               xattr_name = POSIX_ACL_XATTR_ACCESS;
+               if (acl) {
+-                      err = posix_acl_equiv_mode(acl, &inode->i_mode);
+-                      if (err < 0)
++                      err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++                      if (err)
+                               return err;
+               }
+               err = 0;
+--- a/fs/jffs2/acl.c
++++ b/fs/jffs2/acl.c
+@@ -235,9 +235,10 @@ int jffs2_set_acl(struct inode *inode, s
+       case ACL_TYPE_ACCESS:
+               xprefix = JFFS2_XPREFIX_ACL_ACCESS;
+               if (acl) {
+-                      umode_t mode = inode->i_mode;
+-                      rc = posix_acl_equiv_mode(acl, &mode);
+-                      if (rc < 0)
++                      umode_t mode;
++
++                      rc = posix_acl_update_mode(inode, &mode, &acl);
++                      if (rc)
+                               return rc;
+                       if (inode->i_mode != mode) {
+                               struct iattr attr;
+@@ -249,8 +250,6 @@ int jffs2_set_acl(struct inode *inode, s
+                               if (rc < 0)
+                                       return rc;
+                       }
+-                      if (rc == 0)
+-                              acl = NULL;
+               }
+               break;
+       case ACL_TYPE_DEFAULT:
+--- a/fs/jfs/acl.c
++++ b/fs/jfs/acl.c
+@@ -84,13 +84,11 @@ static int __jfs_set_acl(tid_t tid, stru
+       case ACL_TYPE_ACCESS:
+               ea_name = POSIX_ACL_XATTR_ACCESS;
+               if (acl) {
+-                      rc = posix_acl_equiv_mode(acl, &inode->i_mode);
+-                      if (rc < 0)
++                      rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++                      if (rc)
+                               return rc;
+                       inode->i_ctime = CURRENT_TIME;
+                       mark_inode_dirty(inode);
+-                      if (rc == 0)
+-                              acl = NULL;
+               }
+               break;
+       case ACL_TYPE_DEFAULT:
+--- a/fs/ocfs2/acl.c
++++ b/fs/ocfs2/acl.c
+@@ -241,20 +241,16 @@ int ocfs2_set_acl(handle_t *handle,
+       case ACL_TYPE_ACCESS:
+               name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
+               if (acl) {
+-                      umode_t mode = inode->i_mode;
+-                      ret = posix_acl_equiv_mode(acl, &mode);
+-                      if (ret < 0)
+-                              return ret;
+-                      else {
+-                              if (ret == 0)
+-                                      acl = NULL;
++                      umode_t mode;
+-                              ret = ocfs2_acl_set_mode(inode, di_bh,
+-                                                       handle, mode);
+-                              if (ret)
+-                                      return ret;
++                      ret = posix_acl_update_mode(inode, &mode, &acl);
++                      if (ret)
++                              return ret;
+-                      }
++                      ret = ocfs2_acl_set_mode(inode, di_bh,
++                                               handle, mode);
++                      if (ret)
++                              return ret;
+               }
+               break;
+       case ACL_TYPE_DEFAULT:
+--- a/fs/posix_acl.c
++++ b/fs/posix_acl.c
+@@ -594,6 +594,37 @@ no_acl:
+ }
+ EXPORT_SYMBOL_GPL(posix_acl_create);
++/**
++ * posix_acl_update_mode  -  update mode in set_acl
++ *
++ * Update the file mode when setting an ACL: compute the new file permission
++ * bits based on the ACL.  In addition, if the ACL is equivalent to the new
++ * file mode, set *acl to NULL to indicate that no ACL should be set.
++ *
++ * As with chmod, clear the setgit bit if the caller is not in the owning group
++ * or capable of CAP_FSETID (see inode_change_ok).
++ *
++ * Called from set_acl inode operations.
++ */
++int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
++                        struct posix_acl **acl)
++{
++      umode_t mode = inode->i_mode;
++      int error;
++
++      error = posix_acl_equiv_mode(*acl, &mode);
++      if (error < 0)
++              return error;
++      if (error == 0)
++              *acl = NULL;
++      if (!in_group_p(inode->i_gid) &&
++          !capable_wrt_inode_uidgid(inode, CAP_FSETID))
++              mode &= ~S_ISGID;
++      *mode_p = mode;
++      return 0;
++}
++EXPORT_SYMBOL(posix_acl_update_mode);
++
+ /*
+  * Fix up the uids and gids in posix acl extended attributes in place.
+  */
+--- a/fs/reiserfs/xattr_acl.c
++++ b/fs/reiserfs/xattr_acl.c
+@@ -246,13 +246,9 @@ __reiserfs_set_acl(struct reiserfs_trans
+       case ACL_TYPE_ACCESS:
+               name = POSIX_ACL_XATTR_ACCESS;
+               if (acl) {
+-                      error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-                      if (error < 0)
++                      error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++                      if (error)
+                               return error;
+-                      else {
+-                              if (error == 0)
+-                                      acl = NULL;
+-                      }
+               }
+               break;
+       case ACL_TYPE_DEFAULT:
+--- a/fs/xfs/xfs_acl.c
++++ b/fs/xfs/xfs_acl.c
+@@ -286,16 +286,11 @@ xfs_set_acl(struct inode *inode, struct
+               return error;
+       if (type == ACL_TYPE_ACCESS) {
+-              umode_t mode = inode->i_mode;
+-              error = posix_acl_equiv_mode(acl, &mode);
+-
+-              if (error <= 0) {
+-                      acl = NULL;
+-
+-                      if (error < 0)
+-                              return error;
+-              }
++              umode_t mode;
++              error = posix_acl_update_mode(inode, &mode, &acl);
++              if (error)
++                      return error;
+               error = xfs_set_mode(inode, mode);
+               if (error)
+                       return error;
+--- a/include/linux/posix_acl.h
++++ b/include/linux/posix_acl.h
+@@ -95,6 +95,7 @@ extern int set_posix_acl(struct inode *,
+ extern int posix_acl_chmod(struct inode *, umode_t);
+ extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
+               struct posix_acl **);
++extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
+ extern int simple_set_acl(struct inode *, struct posix_acl *, int);
+ extern int simple_acl_create(struct inode *, struct inode *);
diff --git a/queue-3.18/regulator-core-fix-regualtor_ena_gpio_free-not-to-access-pin-after-freeing.patch b/queue-3.18/regulator-core-fix-regualtor_ena_gpio_free-not-to-access-pin-after-freeing.patch
new file mode 100644 (file)
index 0000000..79a313b
--- /dev/null
@@ -0,0 +1,32 @@
+From 60a2362f769cf549dc466134efe71c8bf9fbaaba Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Thu, 4 Dec 2014 19:17:17 +0900
+Subject: regulator: core: Fix regualtor_ena_gpio_free not to access pin after freeing
+
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+
+commit 60a2362f769cf549dc466134efe71c8bf9fbaaba upstream.
+
+After freeing pin from regulator_ena_gpio_free, loop can access
+the pin. So this patch fixes not to access pin after freeing.
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/regulator/core.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1720,6 +1720,8 @@ static void regulator_ena_gpio_free(stru
+                               gpiod_put(pin->gpiod);
+                               list_del(&pin->list);
+                               kfree(pin);
++                              rdev->ena_pin = NULL;
++                              return;
+                       } else {
+                               pin->request_count--;
+                       }
index 2605143614ec94f4304a8711aeeb8d12ef8dd511..2cddc7937a5a8c84f730d5cb1beb0d40e5526fd4 100644 (file)
@@ -35,3 +35,9 @@ net-tg3-avoid-uninitialized-variable-warning.patch
 timerfd-protect-the-might-cancel-mechanism-proper.patch
 handle-mismatched-open-calls.patch
 alsa-pcm-call-kill_fasync-in-stream-lock.patch
+regulator-core-fix-regualtor_ena_gpio_free-not-to-access-pin-after-freeing.patch
+perf-tighten-and-fix-the-grouping-condition.patch
+posix_acl-clear-sgid-bit-when-setting-file-permissions.patch
+l2tp-fix-racy-sock_zapped-flag-check-in-l2tp_ip-6-_bind.patch
+net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch
+mm-avoid-setting-up-anonymous-pages-into-file-mapping.patch