APPLIED: [natty, natty/ti-omap4 CVE 5/5] deal with races in /proc/*/{syscall, stack, personality}
Tim Gardner
tim.gardner at canonical.com
Thu Jul 21 20:09:44 UTC 2011
On 07/21/2011 06:13 AM, Andy Whitcroft wrote:
> From: Al Viro<viro at zeniv.linux.org.uk>
>
> 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>
>
> (backported from commit a9712bc12c40c172e393f85a9b2ba8db4bf59509)
> CVE-2011-1020
> BugLink: http://bugs.launchpad.net/bugs/813026
> Signed-off-by: Andy Whitcroft<apw at canonical.com>
> ---
> fs/proc/base.c | 69 ++++++++++++++++++++++++++++++++++++++++---------------
> 1 files changed, 50 insertions(+), 19 deletions(-)
>
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index bf64fd7..2c0d6f5 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -320,6 +320,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
> @@ -329,6 +346,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);
> @@ -339,15 +357,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, "[<%pK>] %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, "[<%pK>] %pS\n",
> + (void *)entries[i], (void *)entries[i]);
> + }
> + unlock_trace(task);
> }
> kfree(entries);
>
> - return 0;
> + return err;
> }
> #endif
>
> @@ -510,18 +533,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 */
>
> @@ -2748,8 +2775,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;
> }
>
> /*
> @@ -2768,7 +2799,7 @@ 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_IRUGO, proc_pid_limits),
> #ifdef CONFIG_SCHED_DEBUG
> REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
> @@ -2778,7 +2809,7 @@ static const struct pid_entry tgid_base_stuff[] = {
> #endif
> REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
> #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),
> @@ -2806,7 +2837,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),
> @@ -3113,14 +3144,14 @@ 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_IRUGO, proc_pid_limits),
> #ifdef CONFIG_SCHED_DEBUG
> REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
> #endif
> REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
> #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),
> @@ -3147,7 +3178,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),
--
Tim Gardner tim.gardner at canonical.com
More information about the kernel-team
mailing list