diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-15 04:27:04 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-15 04:27:04 -0500 |
commit | d5996b2ff0e26cf7ed4c103084a2d6fc569e7216 (patch) | |
tree | c4d50df299e9c0e07e8ae66406489c01f4c9d6a9 /arch/arm/kernel/stacktrace.c | |
parent | 671289c2872cfc050954ac1dd3131429fca30aad (diff) |
ARM: fix /proc/$PID/stack on SMP
Rabin Vincent reports:
| On SMP, this BUG() in save_stack_trace_tsk() can be easily triggered
| from user space by reading /proc/$PID/stack, where $PID is any pid but
| the current process:
|
| if (tsk != current) {
| #ifdef CONFIG_SMP
| /*
| * What guarantees do we have here that 'tsk'
| * is not running on another CPU?
| */
| BUG();
| #else
Fix this by replacing the BUG() with an entry to terminate the stack
trace, returning an empty trace - I'd rather not expose the dwarf
unwinder to a volatile stack of a running thread.
Reported-by: Rabin Vincent <rabin@rab.in>
Tested-by: Rabin Vincent <rabin@rab.in>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/stacktrace.c')
-rw-r--r-- | arch/arm/kernel/stacktrace.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index c2e112e1a05f..381d23a497c1 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c | |||
@@ -94,10 +94,13 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | |||
94 | if (tsk != current) { | 94 | if (tsk != current) { |
95 | #ifdef CONFIG_SMP | 95 | #ifdef CONFIG_SMP |
96 | /* | 96 | /* |
97 | * What guarantees do we have here that 'tsk' | 97 | * What guarantees do we have here that 'tsk' is not |
98 | * is not running on another CPU? | 98 | * running on another CPU? For now, ignore it as we |
99 | * can't guarantee we won't explode. | ||
99 | */ | 100 | */ |
100 | BUG(); | 101 | if (trace->nr_entries < trace->max_entries) |
102 | trace->entries[trace->nr_entries++] = ULONG_MAX; | ||
103 | return; | ||
101 | #else | 104 | #else |
102 | data.no_sched_functions = 1; | 105 | data.no_sched_functions = 1; |
103 | frame.fp = thread_saved_fp(tsk); | 106 | frame.fp = thread_saved_fp(tsk); |