[kernel] r17998 - in dists/squeeze-security/linux-2.6/debian: . patches/bugfix/all patches/features/all/vserver patches/series
Dann Frazier
dannf at alioth.debian.org
Thu Aug 25 01:39:56 UTC 2011
Author: dannf
Date: Thu Aug 25 01:39:55 2011
New Revision: 17998
Log:
restrict access to /proc/pid/* after setuid exec (CVE-2011-1020)
Added:
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/auxv-require-the-target-or-self-to-be-traceable.patch
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/close-race-in-proc-pid-environ.patch
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/pagemap-close-races-with-suid-execve.patch
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/proc-map-report-errors-sanely.patch
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/proc-syscall-stack-personality-races.patch
Modified:
dists/squeeze-security/linux-2.6/debian/changelog
dists/squeeze-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.6.patch
dists/squeeze-security/linux-2.6/debian/patches/series/35squeeze1
Modified: dists/squeeze-security/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/changelog Thu Aug 25 01:00:52 2011 (r17997)
+++ dists/squeeze-security/linux-2.6/debian/changelog Thu Aug 25 01:39:55 2011 (r17998)
@@ -13,6 +13,7 @@
* net_sched: Fix qdisc_notify() (CVE-2011-2525)
* gro: Only reset frag0 when skb can be pulled (CVE-2011-2723)
* comedi: fix infoleak to userspace (CVE-2011-2909)
+ * restrict access to /proc/pid/* after setuid exec (CVE-2011-1020)
[ Moritz Muehlenhoff ]
* si4713-i2c: avoid potential buffer overflow on si4713 (CVE-2011-2700)
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/auxv-require-the-target-or-self-to-be-traceable.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/auxv-require-the-target-or-self-to-be-traceable.patch Thu Aug 25 01:39:55 2011 (r17998)
@@ -0,0 +1,28 @@
+commit 2fadaef41283aad7100fa73f01998cddaca25833
+Author: Al Viro <viro at zeniv.linux.org.uk>
+Date: Tue Feb 15 22:52:11 2011 -0500
+
+ auxv: require the target to be tracable (or yourself)
+
+ same as for environ, except that we didn't do any checks to
+ prevent access after suid execve
+
+ Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index fc471b8..e94b58b 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -281,9 +281,9 @@ out:
+
+ static int proc_pid_auxv(struct task_struct *task, char *buffer)
+ {
+- int res = 0;
+- struct mm_struct *mm = get_task_mm(task);
+- if (mm) {
++ struct mm_struct *mm = mm_for_maps(task);
++ int res = PTR_ERR(mm);
++ if (mm && !IS_ERR(mm)) {
+ unsigned int nwords = 0;
+ do {
+ nwords += 2;
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/close-race-in-proc-pid-environ.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/close-race-in-proc-pid-environ.patch Thu Aug 25 01:39:55 2011 (r17998)
@@ -0,0 +1,40 @@
+commit d6f64b89d7ff22ce05896ab4a93a653e8d0b123d
+Author: Al Viro <viro at zeniv.linux.org.uk>
+Date: Tue Feb 15 22:26:01 2011 -0500
+
+ close race in /proc/*/environ
+
+ Switch to mm_for_maps(). Maybe we ought to make it r--r--r--,
+ since we do checks on IO anyway...
+
+ Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index c282811..fc471b8 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -919,20 +919,18 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+ if (!task)
+ goto out_no_task;
+
+- if (!ptrace_may_access(task, PTRACE_MODE_READ))
+- goto out;
+-
+ ret = -ENOMEM;
+ page = (char *)__get_free_page(GFP_TEMPORARY);
+ if (!page)
+ goto out;
+
+- ret = 0;
+
+- mm = get_task_mm(task);
+- if (!mm)
++ mm = mm_for_maps(task);
++ ret = PTR_ERR(mm);
++ if (!mm || IS_ERR(mm))
+ goto out_free;
+
++ ret = 0;
+ while (count > 0) {
+ int this_len, retval, max_len;
+
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/pagemap-close-races-with-suid-execve.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/pagemap-close-races-with-suid-execve.patch Thu Aug 25 01:39:55 2011 (r17998)
@@ -0,0 +1,58 @@
+commit ca6b0bf0e086513b9ee5efc0aa5770ecb57778af
+Author: Al Viro <viro at zeniv.linux.org.uk>
+Date: Tue Feb 15 22:04:37 2011 -0500
+
+ pagemap: close races with suid execve
+
+ just use mm_for_maps()
+
+ Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
+ [dannf: backported to Debian's 2.6.32]
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index ae485ab..aca5390 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2552,7 +2552,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+ #ifdef CONFIG_PROC_PAGE_MONITOR
+ REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
+ REG("smaps", S_IRUGO, proc_smaps_operations),
+- REG("pagemap", S_IRUSR, proc_pagemap_operations),
++ REG("pagemap", S_IRUGO, proc_pagemap_operations),
+ #endif
+ #ifdef CONFIG_SECURITY
+ DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
+@@ -2890,7 +2890,7 @@ static const struct pid_entry tid_base_stuff[] = {
+ #ifdef CONFIG_PROC_PAGE_MONITOR
+ REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
+ REG("smaps", S_IRUGO, proc_smaps_operations),
+- REG("pagemap", S_IRUSR, proc_pagemap_operations),
++ REG("pagemap", S_IRUGO, proc_pagemap_operations),
+ #endif
+ #ifdef CONFIG_SECURITY
+ DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 3b7b82a..6e7b065 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -682,7 +682,8 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
+ goto out;
+
+ ret = -EACCES;
+- if (!ptrace_may_access(task, PTRACE_MODE_READ))
++ mm = mm_for_maps(task);
++ if (!mm)
+ goto out_task;
+
+ ret = -EINVAL;
+@@ -695,10 +696,6 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
+ if (!count)
+ goto out_task;
+
+- mm = get_task_mm(task);
+- if (!mm)
+- goto out_task;
+-
+
+ uaddr = (unsigned long)buf & PAGE_MASK;
+ uend = (unsigned long)(buf + count);
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/proc-map-report-errors-sanely.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/proc-map-report-errors-sanely.patch Thu Aug 25 01:39:55 2011 (r17998)
@@ -0,0 +1,86 @@
+commit ec6fd8a4355cda81cd9f06bebc048e83eb514ac7
+Author: Al Viro <viro at zeniv.linux.org.uk>
+Date: Tue Feb 15 22:22:54 2011 -0500
+
+ report errors in /proc/*/*map* sanely
+
+ Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
+ [dannf: backported to Debian's 2.6.32]
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index aca5390..b7567b2 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -235,15 +235,17 @@ static int check_mem_permission(struct task_struct *task)
+ struct mm_struct *mm_for_maps(struct task_struct *task)
+ {
+ struct mm_struct *mm;
++ int err;
+
+- if (mutex_lock_killable(&task->cred_guard_mutex))
+- return NULL;
++ err = mutex_lock_killable(&task->cred_guard_mutex);
++ if (err)
++ return ERR_PTR(err);
+
+ mm = get_task_mm(task);
+ if (mm && mm != current->mm &&
+ !ptrace_may_access(task, PTRACE_MODE_READ)) {
+ mmput(mm);
+- mm = NULL;
++ mm = ERR_PTR(-EACCESS);
+ }
+ mutex_unlock(&task->cred_guard_mutex);
+
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 6e7b065..e62af9b 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -114,11 +114,11 @@ static void *m_start(struct seq_file *m, loff_t *pos)
+
+ priv->task = get_pid_task(priv->pid, PIDTYPE_PID);
+ if (!priv->task)
+- return NULL;
++ return ERR_PTR(-ESRCH);
+
+ mm = mm_for_maps(priv->task);
+- if (!mm)
+- return NULL;
++ if (!mm || IS_ERR(mm))
++ return mm;
+ down_read(&mm->mmap_sem);
+
+ tail_vma = get_gate_vma(priv->task);
+@@ -681,9 +681,9 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
+ if (!task)
+ goto out;
+
+- ret = -EACCES;
+ mm = mm_for_maps(task);
+- if (!mm)
++ ret = PTR_ERR(mm);
++ if (!mm || IS_ERR(mm))
+ goto out_task;
+
+ ret = -EINVAL;
+diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
+index 8f5c05d..522c1e1 100644
+--- a/fs/proc/task_nommu.c
++++ b/fs/proc/task_nommu.c
+@@ -181,13 +181,13 @@ static void *m_start(struct seq_file *m, loff_t *pos)
+ /* pin the task and mm whilst we play with them */
+ priv->task = get_pid_task(priv->pid, PIDTYPE_PID);
+ if (!priv->task)
+- return NULL;
++ return ERR_PTR(-ESRCH);
+
+ mm = mm_for_maps(priv->task);
+- if (!mm) {
++ if (!mm || IS_ERR(mm)) {
+ put_task_struct(priv->task);
+ priv->task = NULL;
+- return NULL;
++ return mm;
+ }
+ down_read(&mm->mmap_sem);
+
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/proc-syscall-stack-personality-races.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/proc-syscall-stack-personality-races.patch Thu Aug 25 01:39:55 2011 (r17998)
@@ -0,0 +1,172 @@
+commit a9712bc12c40c172e393f85a9b2ba8db4bf59509
+Author: Al Viro <viro at zeniv.linux.org.uk>
+Date: Wed Mar 23 15:52:50 2011 -0400
+
+ deal with races in /proc/*/{syscall,stack,personality}
+
+ All of those are rw-r--r-- and all are broken for suid - if you open
+ a file before the target does suid-root exec, you'll be still able
+ to access it. For personality it's not a big deal, but for syscall
+ and stack it's a real problem.
+
+ Fix: check that task is tracable for you at the time of read().
+
+ Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
+ [dannf: backported to Debian's 2.6.32]
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 1be8cb2..8dad8fd 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -330,6 +330,23 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
+ }
+ #endif /* CONFIG_KALLSYMS */
+
++static int lock_trace(struct task_struct *task)
++{
++ int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
++ if (err)
++ return err;
++ if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
++ mutex_unlock(&task->signal->cred_guard_mutex);
++ return -EPERM;
++ }
++ return 0;
++}
++
++static void unlock_trace(struct task_struct *task)
++{
++ mutex_unlock(&task->signal->cred_guard_mutex);
++}
++
+ #ifdef CONFIG_STACKTRACE
+
+ #define MAX_STACK_TRACE_DEPTH 64
+@@ -339,6 +356,7 @@ static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns,
+ {
+ struct stack_trace trace;
+ unsigned long *entries;
++ int err;
+ int i;
+
+ entries = kmalloc(MAX_STACK_TRACE_DEPTH * sizeof(*entries), GFP_KERNEL);
+@@ -349,15 +367,20 @@ static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns,
+ trace.max_entries = MAX_STACK_TRACE_DEPTH;
+ trace.entries = entries;
+ trace.skip = 0;
+- save_stack_trace_tsk(task, &trace);
+
+- for (i = 0; i < trace.nr_entries; i++) {
+- seq_printf(m, "[<%p>] %pS\n",
+- (void *)entries[i], (void *)entries[i]);
++ err = lock_trace(task);
++ if (!err) {
++ save_stack_trace_tsk(task, &trace);
++
++ for (i = 0; i < trace.nr_entries; i++) {
++ seq_printf(m, "[<%p>] %pS\n",
++ (void *)entries[i], (void *)entries[i]);
++ }
++ unlock_trace(task);
+ }
+ kfree(entries);
+
+- return 0;
++ return err;
+ }
+ #endif
+
+@@ -529,18 +552,22 @@ static int proc_pid_syscall(struct task_struct *task, char *buffer)
+ {
+ long nr;
+ unsigned long args[6], sp, pc;
++ int res = lock_trace(task);
++ if (res)
++ return res;
+
+ if (task_current_syscall(task, &nr, args, 6, &sp, &pc))
+- return sprintf(buffer, "running\n");
+-
+- if (nr < 0)
+- return sprintf(buffer, "%ld 0x%lx 0x%lx\n", nr, sp, pc);
+-
+- return sprintf(buffer,
++ res = sprintf(buffer, "running\n");
++ else if (nr < 0)
++ res = sprintf(buffer, "%ld 0x%lx 0x%lx\n", nr, sp, pc);
++ else
++ res = sprintf(buffer,
+ "%ld 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
+ nr,
+ args[0], args[1], args[2], args[3], args[4], args[5],
+ sp, pc);
++ unlock_trace(task);
++ return res;
+ }
+ #endif /* CONFIG_HAVE_ARCH_TRACEHOOK */
+
+@@ -2507,8 +2534,12 @@ static int proc_tgid_io_accounting(struct task_struct *task, char *buffer)
+ static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
+ struct pid *pid, struct task_struct *task)
+ {
+- seq_printf(m, "%08x\n", task->personality);
+- return 0;
++ int err = lock_trace(task);
++ if (!err) {
++ seq_printf(m, "%08x\n", task->personality);
++ unlock_trace(task);
++ }
++ return err;
+ }
+
+ /*
+@@ -2527,13 +2558,13 @@ static const struct pid_entry tgid_base_stuff[] = {
+ REG("environ", S_IRUSR, proc_environ_operations),
+ INF("auxv", S_IRUSR, proc_pid_auxv),
+ ONE("status", S_IRUGO, proc_pid_status),
+- ONE("personality", S_IRUSR, proc_pid_personality),
++ ONE("personality", S_IRUGO, proc_pid_personality),
+ INF("limits", S_IRUSR, proc_pid_limits),
+ #ifdef CONFIG_SCHED_DEBUG
+ REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
+ #endif
+ #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+- INF("syscall", S_IRUSR, proc_pid_syscall),
++ INF("syscall", S_IRUGO, proc_pid_syscall),
+ #endif
+ INF("cmdline", S_IRUGO, proc_pid_cmdline),
+ ONE("stat", S_IRUGO, proc_tgid_stat),
+@@ -2561,7 +2592,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+ INF("wchan", S_IRUGO, proc_pid_wchan),
+ #endif
+ #ifdef CONFIG_STACKTRACE
+- ONE("stack", S_IRUSR, proc_pid_stack),
++ ONE("stack", S_IRUGO, proc_pid_stack),
+ #endif
+ #ifdef CONFIG_SCHEDSTATS
+ INF("schedstat", S_IRUGO, proc_pid_schedstat),
+@@ -2866,13 +2897,13 @@ static const struct pid_entry tid_base_stuff[] = {
+ REG("environ", S_IRUSR, proc_environ_operations),
+ INF("auxv", S_IRUSR, proc_pid_auxv),
+ ONE("status", S_IRUGO, proc_pid_status),
+- ONE("personality", S_IRUSR, proc_pid_personality),
++ ONE("personality", S_IRUGO, proc_pid_personality),
+ INF("limits", S_IRUSR, proc_pid_limits),
+ #ifdef CONFIG_SCHED_DEBUG
+ REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
+ #endif
+ #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+- INF("syscall", S_IRUSR, proc_pid_syscall),
++ INF("syscall", S_IRUGO, proc_pid_syscall),
+ #endif
+ INF("cmdline", S_IRUGO, proc_pid_cmdline),
+ ONE("stat", S_IRUGO, proc_tid_stat),
+@@ -2899,7 +2930,7 @@ static const struct pid_entry tid_base_stuff[] = {
+ INF("wchan", S_IRUGO, proc_pid_wchan),
+ #endif
+ #ifdef CONFIG_STACKTRACE
+- ONE("stack", S_IRUSR, proc_pid_stack),
++ ONE("stack", S_IRUGO, proc_pid_stack),
+ #endif
+ #ifdef CONFIG_SCHEDSTATS
+ INF("schedstat", S_IRUGO, proc_pid_schedstat),
Modified: dists/squeeze-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.6.patch
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.6.patch Thu Aug 25 01:00:52 2011 (r17997)
+++ dists/squeeze-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.6.patch Thu Aug 25 01:39:55 2011 (r17998)
@@ -6869,9 +6869,9 @@
INF("oom_score", S_IRUGO, proc_oom_score),
REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
#ifdef CONFIG_AUDITSYSCALL
-@@ -2577,6 +2598,7 @@ static const struct pid_entry tgid_base_
+@@ -2621,6 +2642,7 @@ static const struct pid_entry tgid_base_
#ifdef CONFIG_TASK_IO_ACCOUNTING
- INF("io", S_IRUGO, proc_tgid_io_accounting),
+ INF("io", S_IRUSR, proc_tgid_io_accounting),
#endif
+ ONE("nsproxy", S_IRUGO, proc_pid_nsproxy),
};
Modified: dists/squeeze-security/linux-2.6/debian/patches/series/35squeeze1
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/patches/series/35squeeze1 Thu Aug 25 01:00:52 2011 (r17997)
+++ dists/squeeze-security/linux-2.6/debian/patches/series/35squeeze1 Thu Aug 25 01:39:55 2011 (r17998)
@@ -16,3 +16,8 @@
+ bugfix/all/gro-only-reset-frag0-when-skb-can-be-pulled.patch
+ bugfix/all/comedi-fix-infoleak-to-userspace.patch
+ bugfix/all/CVE-2011-3188.patch
++ bugfix/all/pagemap-close-races-with-suid-execve.patch
++ bugfix/all/proc-map-report-errors-sanely.patch
++ bugfix/all/close-race-in-proc-pid-environ.patch
++ bugfix/all/auxv-require-the-target-or-self-to-be-traceable.patch
++ bugfix/all/proc-syscall-stack-personality-races.patch
More information about the Kernel-svn-changes
mailing list