From: Greg Kroah-Hartman Date: Thu, 4 May 2017 19:43:07 +0000 (-0700) Subject: 3.18-stable patches X-Git-Tag: v3.18.52~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6fd40e426b2e4c8b719a6b345a8b9a90fb9f5b59;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches 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 --- 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 index 00000000000..e6daed8ea5b --- /dev/null +++ b/queue-3.18/l2tp-fix-racy-sock_zapped-flag-check-in-l2tp_ip-6-_bind.patch @@ -0,0 +1,167 @@ +From 32c231164b762dddefa13af5a0101032c70b50ef Mon Sep 17 00:00:00 2001 +From: Guillaume Nault +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 + +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: + [] dump_stack+0xb3/0x118 lib/dump_stack.c:15 + [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156 + [< inline >] print_address_description mm/kasan/report.c:194 + [] kasan_report_error+0x1f6/0x4d0 mm/kasan/report.c:283 + [< inline >] kasan_report mm/kasan/report.c:303 + [] __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 + [] l2tp_ip6_close+0x22e/0x290 net/l2tp/l2tp_ip6.c:239 + [] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415 + [] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422 + [] sock_release+0x8d/0x1d0 net/socket.c:570 + [] sock_close+0x16/0x20 net/socket.c:1017 + [] __fput+0x28c/0x780 fs/file_table.c:208 + [] ____fput+0x15/0x20 fs/file_table.c:244 + [] task_work_run+0xf9/0x170 + [] do_exit+0x85e/0x2a00 + [] do_group_exit+0x108/0x330 + [] get_signal+0x617/0x17a0 kernel/signal.c:2307 + [] do_signal+0x7f/0x18f0 + [] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156 + [< inline >] prepare_exit_to_usermode arch/x86/entry/common.c:190 + [] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259 + [] entry_SYSCALL_64_fastpath+0xc4/0xc6 +Object at ffff8800081b0ec0, in cache L2TP/IPv6 size: 1448 +Allocated: +PID = 10987 + [ 1116.897025] [] save_stack_trace+0x16/0x20 + [ 1116.897025] [] save_stack+0x46/0xd0 + [ 1116.897025] [] kasan_kmalloc+0xad/0xe0 + [ 1116.897025] [] 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] [] kmem_cache_alloc+0xc8/0x2b0 mm/slub.c:2721 + [ 1116.897025] [] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1326 + [ 1116.897025] [] sk_alloc+0x38/0xae0 net/core/sock.c:1388 + [ 1116.897025] [] inet6_create+0x2d7/0x1000 net/ipv6/af_inet6.c:182 + [ 1116.897025] [] __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] [] SyS_socket+0xef/0x1b0 net/socket.c:1203 + [ 1116.897025] [] entry_SYSCALL_64_fastpath+0x23/0xc6 +Freed: +PID = 10987 + [ 1116.897025] [] save_stack_trace+0x16/0x20 + [ 1116.897025] [] save_stack+0x46/0xd0 + [ 1116.897025] [] 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] [] kmem_cache_free+0xc8/0x330 mm/slub.c:2973 + [ 1116.897025] [< inline >] sk_prot_free net/core/sock.c:1369 + [ 1116.897025] [] __sk_destruct+0x32b/0x4f0 net/core/sock.c:1444 + [ 1116.897025] [] sk_destruct+0x44/0x80 net/core/sock.c:1452 + [ 1116.897025] [] __sk_free+0x53/0x220 net/core/sock.c:1460 + [ 1116.897025] [] sk_free+0x23/0x30 net/core/sock.c:1471 + [ 1116.897025] [] sk_common_release+0x28c/0x3e0 ./include/net/sock.h:1589 + [ 1116.897025] [] l2tp_ip6_close+0x1fe/0x290 net/l2tp/l2tp_ip6.c:243 + [ 1116.897025] [] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415 + [ 1116.897025] [] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422 + [ 1116.897025] [] sock_release+0x8d/0x1d0 net/socket.c:570 + [ 1116.897025] [] sock_close+0x16/0x20 net/socket.c:1017 + [ 1116.897025] [] __fput+0x28c/0x780 fs/file_table.c:208 + [ 1116.897025] [] ____fput+0x15/0x20 fs/file_table.c:244 + [ 1116.897025] [] task_work_run+0xf9/0x170 + [ 1116.897025] [] do_exit+0x85e/0x2a00 + [ 1116.897025] [] do_group_exit+0x108/0x330 + [ 1116.897025] [] get_signal+0x617/0x17a0 kernel/signal.c:2307 + [ 1116.897025] [] do_signal+0x7f/0x18f0 + [ 1116.897025] [] 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] [] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259 + [ 1116.897025] [] 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 +Reported-by: Andrey Konovalov +Tested-by: Baozeng Ding +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..89a0b24e7ca --- /dev/null +++ b/queue-3.18/mm-avoid-setting-up-anonymous-pages-into-file-mapping.patch @@ -0,0 +1,71 @@ +From 6b7339f4c31ad69c8e9c0b2859276e22cf72176d Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Mon, 6 Jul 2015 23:18:37 +0300 +Subject: mm: avoid setting up anonymous pages into file mapping + +From: Kirill A. Shutemov + +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 +Acked-by: Oleg Nesterov +Cc: Andrew Morton +Cc: Willy Tarreau +Signed-off-by: Linus Torvalds +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..764c9fd39c2 --- /dev/null +++ b/queue-3.18/net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch @@ -0,0 +1,51 @@ +From b98b0bc8c431e3ceb4b26b0dfc8db509518fb290 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 2 Dec 2016 09:44:53 -0800 +Subject: net: avoid signed overflows for SO_{SND|RCV}BUFFORCE + +From: Eric Dumazet + +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 +Reported-by: Andrey Konovalov +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..34054d99864 --- /dev/null +++ b/queue-3.18/perf-tighten-and-fix-the-grouping-condition.patch @@ -0,0 +1,91 @@ +From c3c87e770458aa004bd7ed3f29945ff436fd6511 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Fri, 23 Jan 2015 11:19:48 +0100 +Subject: perf: Tighten (and fix) the grouping condition + +From: Peter Zijlstra + +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) +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Link: http://lkml.kernel.org/r/20150123125834.090683288@infradead.org +Signed-off-by: Ingo Molnar +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9ec056dabf5 --- /dev/null +++ b/queue-3.18/posix_acl-clear-sgid-bit-when-setting-file-permissions.patch @@ -0,0 +1,386 @@ +From 073931017b49d9458aa351605b43a7e34598caef Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 19 Sep 2016 17:39:09 +0200 +Subject: posix_acl: Clear SGID bit when setting file permissions + +From: Jan Kara + +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 +Reviewed-by: Jeff Layton +Signed-off-by: Jan Kara +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..79a313bff14 --- /dev/null +++ b/queue-3.18/regulator-core-fix-regualtor_ena_gpio_free-not-to-access-pin-after-freeing.patch @@ -0,0 +1,32 @@ +From 60a2362f769cf549dc466134efe71c8bf9fbaaba Mon Sep 17 00:00:00 2001 +From: Seung-Woo Kim +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 + +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 +Signed-off-by: Mark Brown +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + 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--; + } diff --git a/queue-3.18/series b/queue-3.18/series index 2605143614e..2cddc7937a5 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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