]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Nov 2013 17:28:28 +0000 (09:28 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Nov 2013 17:28:28 +0000 (09:28 -0800)
added patches:
exec-ptrace-fix-get_dumpable-incorrect-tests.patch

queue-3.11/exec-ptrace-fix-get_dumpable-incorrect-tests.patch [new file with mode: 0644]
queue-3.11/series

diff --git a/queue-3.11/exec-ptrace-fix-get_dumpable-incorrect-tests.patch b/queue-3.11/exec-ptrace-fix-get_dumpable-incorrect-tests.patch
new file mode 100644 (file)
index 0000000..473cf1c
--- /dev/null
@@ -0,0 +1,116 @@
+From d049f74f2dbe71354d43d393ac3a188947811348 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Tue, 12 Nov 2013 15:11:17 -0800
+Subject: exec/ptrace: fix get_dumpable() incorrect tests
+
+From: Kees Cook <keescook@chromium.org>
+
+commit d049f74f2dbe71354d43d393ac3a188947811348 upstream.
+
+The get_dumpable() return value is not boolean.  Most users of the
+function actually want to be testing for non-SUID_DUMP_USER(1) rather than
+SUID_DUMP_DISABLE(0).  The SUID_DUMP_ROOT(2) is also considered a
+protected state.  Almost all places did this correctly, excepting the two
+places fixed in this patch.
+
+Wrong logic:
+    if (dumpable == SUID_DUMP_DISABLE) { /* be protective */ }
+        or
+    if (dumpable == 0) { /* be protective */ }
+        or
+    if (!dumpable) { /* be protective */ }
+
+Correct logic:
+    if (dumpable != SUID_DUMP_USER) { /* be protective */ }
+        or
+    if (dumpable != 1) { /* be protective */ }
+
+Without this patch, if the system had set the sysctl fs/suid_dumpable=2, a
+user was able to ptrace attach to processes that had dropped privileges to
+that user.  (This may have been partially mitigated if Yama was enabled.)
+
+The macros have been moved into the file that declares get/set_dumpable(),
+which means things like the ia64 code can see them too.
+
+CVE-2013-2929
+
+Reported-by: Vasily Kulikov <segoon@openwall.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Cc: "Luck, Tony" <tony.luck@intel.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/ia64/include/asm/processor.h |    2 +-
+ fs/exec.c                         |    6 ++++++
+ include/linux/binfmts.h           |    3 ---
+ include/linux/sched.h             |    4 ++++
+ kernel/ptrace.c                   |    3 ++-
+ 5 files changed, 13 insertions(+), 5 deletions(-)
+
+--- a/arch/ia64/include/asm/processor.h
++++ b/arch/ia64/include/asm/processor.h
+@@ -319,7 +319,7 @@ struct thread_struct {
+       regs->loadrs = 0;                                                                       \
+       regs->r8 = get_dumpable(current->mm);   /* set "don't zap registers" flag */            \
+       regs->r12 = new_sp - 16;        /* allocate 16 byte scratch area */                     \
+-      if (unlikely(!get_dumpable(current->mm))) {                                                     \
++      if (unlikely(get_dumpable(current->mm) != SUID_DUMP_USER)) {    \
+               /*                                                                              \
+                * Zap scratch regs to avoid leaking bits between processes with different      \
+                * uid/privileges.                                                              \
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1670,6 +1670,12 @@ int __get_dumpable(unsigned long mm_flag
+       return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret;
+ }
++/*
++ * This returns the actual value of the suid_dumpable flag. For things
++ * that are using this for checking for privilege transitions, it must
++ * test against SUID_DUMP_USER rather than treating it as a boolean
++ * value.
++ */
+ int get_dumpable(struct mm_struct *mm)
+ {
+       return __get_dumpable(mm->flags);
+--- a/include/linux/binfmts.h
++++ b/include/linux/binfmts.h
+@@ -99,9 +99,6 @@ extern void setup_new_exec(struct linux_
+ extern void would_dump(struct linux_binprm *, struct file *);
+ extern int suid_dumpable;
+-#define SUID_DUMP_DISABLE     0       /* No setuid dumping */
+-#define SUID_DUMP_USER                1       /* Dump as user of process */
+-#define SUID_DUMP_ROOT                2       /* Dump as root */
+ /* Stack area protections */
+ #define EXSTACK_DEFAULT   0   /* Whatever the arch defaults to */
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -330,6 +330,10 @@ static inline void arch_pick_mmap_layout
+ extern void set_dumpable(struct mm_struct *mm, int value);
+ extern int get_dumpable(struct mm_struct *mm);
++#define SUID_DUMP_DISABLE     0       /* No setuid dumping */
++#define SUID_DUMP_USER                1       /* Dump as user of process */
++#define SUID_DUMP_ROOT                2       /* Dump as root */
++
+ /* mm flags */
+ /* dumpable bits */
+ #define MMF_DUMPABLE      0  /* core dump is permitted */
+--- a/kernel/ptrace.c
++++ b/kernel/ptrace.c
+@@ -257,7 +257,8 @@ ok:
+       if (task->mm)
+               dumpable = get_dumpable(task->mm);
+       rcu_read_lock();
+-      if (!dumpable && !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
++      if (dumpable != SUID_DUMP_USER &&
++          !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
+               rcu_read_unlock();
+               return -EPERM;
+       }
index a8b6dbe45ed4e83078b48849915c958eb7d4e59d..d9f81d5263cc6eff7d3b93d07853a6baa10c6ca9 100644 (file)
@@ -33,3 +33,4 @@ rt2x00-rt2800lib-fix-vgc-adjustment-for-rt5592.patch
 rt2x00-fix-ht-tx-descriptor-settings-regression.patch
 bluetooth-revert-bluetooth-add-missing-reset_resume-dev_pm_ops.patch
 revert-ima-policy-for-ramfs.patch
+exec-ptrace-fix-get_dumpable-incorrect-tests.patch