projects
/
openwrt
/
staging
/
blogic.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
e3bc804
)
powerpc: Fix null pointer deref in perf hardware breakpoints
author
Michael Neuling
<
[email protected]
>
Wed, 22 Aug 2012 20:30:43 +0000
(20:30 +0000)
committer
Benjamin Herrenschmidt
<
[email protected]
>
Fri, 24 Aug 2012 10:26:04 +0000
(20:26 +1000)
Currently if you are doing a global perf recording with hardware
breakpoints (ie perf record -e mem:0xdeadbeef -a), you can oops with:
Faulting instruction address: 0xc000000000738890
cpu 0xc: Vector: 300 (Data Access) at [
c0000003f76af8d0
]
pc:
c000000000738890
: .hw_breakpoint_handler+0xa0/0x1e0
lr:
c000000000738830
: .hw_breakpoint_handler+0x40/0x1e0
sp:
c0000003f76afb50
msr:
8000000000001032
dar: 6f0
dsisr:
42000000
current = 0xc0000003f765ac00
paca = 0xc00000000f262a00 softe: 0 irq_happened: 0x01
pid = 6810, comm = loop-read
enter ? for help
[
c0000003f76afbe0
]
c00000000073cd04
.notifier_call_chain.isra.0+0x84/0xe0
[
c0000003f76afc80
]
c00000000073cdbc
.notify_die+0x3c/0x60
[
c0000003f76afd20
]
c0000000000139f0
.do_dabr+0x40/0xf0
[
c0000003f76afe30
]
c000000000005a9c
handle_dabr_fault+0x14/0x48
--- Exception: 300 (Data Access) at
0000000010000480
SP (
ff8679e0
) is in userspace
This is because we don't check to see if the break point is associated
with task before we deference the task_struct pointer.
This changes the update to use current.
Signed-off-by: Michael Neuling <
[email protected]
>
Signed-off-by: Benjamin Herrenschmidt <
[email protected]
>
arch/powerpc/kernel/hw_breakpoint.c
patch
|
blob
|
history
diff --git
a/arch/powerpc/kernel/hw_breakpoint.c
b/arch/powerpc/kernel/hw_breakpoint.c
index f3a82dde61dbfe8b469a63d4874f2de53bf1b476..956a4c496de942d93853f42f2db1067f45cf0085 100644
(file)
--- a/
arch/powerpc/kernel/hw_breakpoint.c
+++ b/
arch/powerpc/kernel/hw_breakpoint.c
@@
-253,7
+253,7
@@
int __kprobes hw_breakpoint_handler(struct die_args *args)
/* Do not emulate user-space instructions, instead single-step them */
if (user_mode(regs)) {
-
bp->ctx->task
->thread.last_hit_ubp = bp;
+
current
->thread.last_hit_ubp = bp;
regs->msr |= MSR_SE;
goto out;
}