mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 21:51:05 +00:00
powerpc, hw_breakpoint: Fix off-by-one in checking access address
The code would accept an access to an address one byte past the end of the requested range as legitimate, due to having a "<=" rather than a "<". This fixes that and cleans up the code a bit. Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
e3e94084ad
commit
574cb24899
1 changed files with 7 additions and 16 deletions
|
@ -197,7 +197,6 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
|
||||||
*/
|
*/
|
||||||
int __kprobes hw_breakpoint_handler(struct die_args *args)
|
int __kprobes hw_breakpoint_handler(struct die_args *args)
|
||||||
{
|
{
|
||||||
bool is_ptrace_bp = false;
|
|
||||||
int rc = NOTIFY_STOP;
|
int rc = NOTIFY_STOP;
|
||||||
struct perf_event *bp;
|
struct perf_event *bp;
|
||||||
struct pt_regs *regs = args->regs;
|
struct pt_regs *regs = args->regs;
|
||||||
|
@ -208,6 +207,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
|
||||||
|
|
||||||
/* Disable breakpoints during exception handling */
|
/* Disable breakpoints during exception handling */
|
||||||
set_dabr(0);
|
set_dabr(0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The counter may be concurrently released but that can only
|
* The counter may be concurrently released but that can only
|
||||||
* occur from a call_rcu() path. We can then safely fetch
|
* occur from a call_rcu() path. We can then safely fetch
|
||||||
|
@ -220,8 +220,6 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
|
||||||
if (!bp)
|
if (!bp)
|
||||||
goto out;
|
goto out;
|
||||||
info = counter_arch_bp(bp);
|
info = counter_arch_bp(bp);
|
||||||
is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ?
|
|
||||||
true : false;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return early after invoking user-callback function without restoring
|
* Return early after invoking user-callback function without restoring
|
||||||
|
@ -229,7 +227,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
|
||||||
* one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
|
* one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
|
||||||
* generated in do_dabr().
|
* generated in do_dabr().
|
||||||
*/
|
*/
|
||||||
if (is_ptrace_bp) {
|
if (bp->overflow_handler == ptrace_triggered) {
|
||||||
perf_bp_event(bp, regs);
|
perf_bp_event(bp, regs);
|
||||||
rc = NOTIFY_DONE;
|
rc = NOTIFY_DONE;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -237,19 +235,12 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify if dar lies within the address range occupied by the symbol
|
* Verify if dar lies within the address range occupied by the symbol
|
||||||
* being watched to filter extraneous exceptions.
|
* being watched to filter extraneous exceptions. If it doesn't,
|
||||||
|
* we still need to single-step the instruction, but we don't
|
||||||
|
* generate an event.
|
||||||
*/
|
*/
|
||||||
if (!((bp->attr.bp_addr <= dar) &&
|
info->extraneous_interrupt = !((bp->attr.bp_addr <= dar) &&
|
||||||
(dar <= (bp->attr.bp_addr + bp->attr.bp_len)))) {
|
(dar - bp->attr.bp_addr < bp->attr.bp_len));
|
||||||
/*
|
|
||||||
* This exception is triggered not because of a memory access
|
|
||||||
* on the monitored variable but in the double-word address
|
|
||||||
* range in which it is contained. We will consume this
|
|
||||||
* exception, considering it as 'noise'.
|
|
||||||
*/
|
|
||||||
info->extraneous_interrupt = true;
|
|
||||||
} else
|
|
||||||
info->extraneous_interrupt = false;
|
|
||||||
|
|
||||||
/* Do not emulate user-space instructions, instead single-step them */
|
/* Do not emulate user-space instructions, instead single-step them */
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue