Messages in this thread Patch in this message | | | Date | Tue, 16 Dec 2008 13:50:00 +0100 | From | Ingo Molnar <> | Subject | Re: [patch] Performance Counters for Linux, v4 |
| |
* Pavel Machek <pavel@suse.cz> wrote:
> Hmm, if I timec some setuid program, what happens?
yes, i already had a quick look at that a few days ago when i implemented counter inheritance (for different reasons) and couldnt find the cleanest place to put the exec() flushing into so i procrastinated that a bit :)
> Performance counters seem like great tool to pull secret keys out of > other processes :-).
if you worry about _that_ angle you also have to:
- turn off the cycle counter
- turn off precise utimes
- plus you have to forbid SMT CPUs as well. On HT a task could co-schedule with your setuid task and observe its timing characteristics via its _own_ behavior. (which is impacted by whatever is running on another SMT/HT thread.)
the real exec() worry are: active, IRQ driven samples/events. Not possible yet via the current iteration of counter inheritance (hence my procrastination) - but it makes sense and that's why i was looking at the exec() angle.
and that will flush simple counters too, removing your theoretical attack angle as well.
So how about the patch below?
Ingo
---------------> Subject: perfcounters: flush on setuid exec From: Ingo Molnar <mingo@elte.hu> Date: Tue Dec 16 13:40:44 CET 2008
Pavel Machek pointed out that performance counters should be flushed when crossing protection domains on setuid execution.
Reported-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Ingo Molnar <mingo@elte.hu> --- fs/exec.c | 8 ++++++++ 1 file changed, 8 insertions(+)
Index: linux/fs/exec.c =================================================================== --- linux.orig/fs/exec.c +++ linux/fs/exec.c @@ -33,6 +33,7 @@ #include <linux/string.h> #include <linux/init.h> #include <linux/pagemap.h> +#include <linux/perf_counter.h> #include <linux/highmem.h> #include <linux/spinlock.h> #include <linux/key.h> @@ -1015,6 +1016,13 @@ int flush_old_exec(struct linux_binprm * set_dumpable(current->mm, suid_dumpable); } + /* + * Flush performance counters when crossing a + * security domain: + */ + if (!get_dumpable(current->mm)) + perf_counter_exit_task(current); + /* An exec changes our domain. We are no longer part of the thread group */
| |