On Wed, Sep 30, 2015 at 6:59 AM, Ingo Molnar <mi...@kernel.org> wrote: > > * Thomas Gleixner <t...@linutronix.de> wrote: > >> On Wed, 30 Sep 2015, Ingo Molnar wrote: >> > diff --git a/fs/proc/array.c b/fs/proc/array.c >> > index f60f0121e331..99082730b2ac 100644 >> > --- a/fs/proc/array.c >> > +++ b/fs/proc/array.c >> > @@ -507,7 +507,7 @@ static int do_task_stat(struct seq_file *m, struct >> > pid_namespace *ns, >> > seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL); >> > seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL); >> > seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL); >> > - seq_put_decimal_ull(m, ' ', wchan); >> > + seq_puts(m, " 0"); /* Used to be numeric wchan - replaced by >> > /proc/PID/wchan */ >> >> That should get rid of all wchan usage in do_task_stat() > > Indeed - updated patch attached. > > Thanks, > > Ingo > > ================================> > From 985037cd05b379240dd381b29c2525758c665bb0 Mon Sep 17 00:00:00 2001 > From: Ingo Molnar <mi...@kernel.org> > Date: Wed, 30 Sep 2015 09:15:37 +0200 > Subject: [PATCH] fs/proc: Don't expose absolute kernel addresses via wchan > > So wchan leaks absolute kernel addresses to unprivileged > user-space, of kernel functions that sleep: > > static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns, > struct pid *pid, struct task_struct *task) > { > unsigned long wchan; > char symname[KSYM_NAME_LEN]; > > wchan = get_wchan(task); > > if (lookup_symbol_name(wchan, symname) < 0) { > if (!ptrace_may_access(task, PTRACE_MODE_READ)) > return 0; > seq_printf(m, "%lu", wchan); > } else { > seq_printf(m, "%s", symname); > } > > return 0; > } > > So for example it trivially leaks the KASLR offset to any local > attacker: > > fomalhaut:~> printf "%016lx\n" $(cat /proc/$$/stat | cut -d' ' -f35) > ffffffff8123b380 > > Most real-life uses of wchan are symbolic: > > ps -eo pid:10,tid:10,wchan:30,comm > > and procps uses /proc/PID/wchan, not the absolute address in > /proc/PID/stat: > > triton:~/tip> strace -f ps -eo pid:10,tid:10,wchan:30,comm 2>&1 | grep > wchan | tail -1 > open("/proc/30833/wchan", O_RDONLY) = 6 > > These days there's very little legitimate reason user-space > would be interested in the absolute address. The absolute > address is mostly historic: from the days when we didn't have > kallsyms and user-space procps had to do the decoding itself via > the System.map. > > So this patch sets all numeric output to 0 and keeps the > symbolic output in /proc/PID/wchan. > > ( The absolute sleep address can generally still be profiled via > perf, by tasks with sufficient privileges. ) > > Cc: Al Viro <v...@zeniv.linux.org.uk> > Cc: Alexander Potapenko <gli...@google.com> > Cc: Andrey Konovalov <andreyk...@google.com> > Cc: Andrey Ryabinin <ryabinin....@gmail.com> > Cc: Andy Lutomirski <l...@amacapital.net> > Cc: Andy Lutomirski <l...@kernel.org> > Cc: Borislav Petkov <b...@alien8.de> > Cc: Denys Vlasenko <dvlas...@redhat.com> > Cc: Dmitry Vyukov <dvyu...@google.com> > Cc: Kees Cook <keesc...@chromium.org> > Cc: Kostya Serebryany <k...@google.com> > Cc: Linus Torvalds <torva...@linux-foundation.org> > Cc: Mike Galbraith <efa...@gmx.de> > Cc: Peter Zijlstra <a.p.zijls...@chello.nl> > Cc: Peter Zijlstra <pet...@infradead.org> > Cc: Sasha Levin <sasha.le...@oracle.com> > Cc: Thomas Gleixner <t...@linutronix.de> > Cc: kasan-dev <kasan-...@googlegroups.com> > Cc: linux-kernel@vger.kernel.org > Link: http://lkml.kernel.org/r/20150930071537.ga19...@gmail.com > Signed-off-by: Ingo Molnar <mi...@kernel.org> > --- > fs/proc/array.c | 6 ++---- > fs/proc/base.c | 7 +------ > 2 files changed, 3 insertions(+), 10 deletions(-) > > diff --git a/fs/proc/array.c b/fs/proc/array.c > index f60f0121e331..ad5ad1e376ad 100644 > --- a/fs/proc/array.c > +++ b/fs/proc/array.c > @@ -375,7 +375,7 @@ int proc_pid_status(struct seq_file *m, struct > pid_namespace *ns, > static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, > struct pid *pid, struct task_struct *task, int whole) > { > - unsigned long vsize, eip, esp, wchan = ~0UL; > + unsigned long vsize, eip, esp; > int priority, nice; > int tty_pgrp = -1, tty_nr = 0; > sigset_t sigign, sigcatch; > @@ -454,8 +454,6 @@ static int do_task_stat(struct seq_file *m, struct > pid_namespace *ns, > unlock_task_sighand(task, &flags); > } > > - if (permitted && (!whole || num_threads < 2)) > - wchan = get_wchan(task); > if (!whole) { > min_flt = task->min_flt; > maj_flt = task->maj_flt; > @@ -507,7 +505,7 @@ static int do_task_stat(struct seq_file *m, struct > pid_namespace *ns, > seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL); > seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL); > seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL); > - seq_put_decimal_ull(m, ' ', wchan); > + seq_puts(m, " 0"); /* Used to be numeric wchan - replaced by > /proc/PID/wchan */
Probably should also update Documentation/filesystems/proc.txt with something like: --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -310,7 +310,7 @@ Table 1-4: Contents of the stat files (as of 2.6.30-rc7) blocked bitmap of blocked signals sigign bitmap of ignored signals sigcatch bitmap of caught signals - wchan address where process went to sleep + 0 (place holder, was wchan, see /proc/PID/wchan instead) 0 (place holder) 0 (place holder) exit_signal signal to send to parent thread on exit > seq_put_decimal_ull(m, ' ', 0); > seq_put_decimal_ull(m, ' ', 0); > seq_put_decimal_ll(m, ' ', task->exit_signal); > diff --git a/fs/proc/base.c b/fs/proc/base.c > index b25eee4cead5..2fdbf303e3eb 100644 > --- a/fs/proc/base.c > +++ b/fs/proc/base.c > @@ -430,13 +430,8 @@ static int proc_pid_wchan(struct seq_file *m, struct > pid_namespace *ns, > > wchan = get_wchan(task); > > - if (lookup_symbol_name(wchan, symname) < 0) { > - if (!ptrace_may_access(task, PTRACE_MODE_READ)) > - return 0; > - seq_printf(m, "%lu", wchan); > - } else { > + if (!lookup_symbol_name(wchan, symname)) > seq_printf(m, "%s", symname); > - } > > return 0; > } Acked-by: Kees Cook <keesc...@chromium.org> -Kees -- Kees Cook Chrome OS Security -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/