|
@@ -526,6 +526,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
|
|
|
dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
|
|
{
|
|
|
struct task_struct *tsk = current;
|
|
|
+ int user_icebp = 0;
|
|
|
unsigned long dr6;
|
|
|
int si_code;
|
|
|
|
|
@@ -534,6 +535,14 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
|
|
/* Filter out all the reserved bits which are preset to 1 */
|
|
|
dr6 &= ~DR6_RESERVED;
|
|
|
|
|
|
+ /*
|
|
|
+ * If dr6 has no reason to give us about the origin of this trap,
|
|
|
+ * then it's very likely the result of an icebp/int01 trap.
|
|
|
+ * User wants a sigtrap for that.
|
|
|
+ */
|
|
|
+ if (!dr6 && user_mode(regs))
|
|
|
+ user_icebp = 1;
|
|
|
+
|
|
|
/* Catch kmemcheck conditions first of all! */
|
|
|
if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
|
|
|
return;
|
|
@@ -575,7 +584,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
|
|
regs->flags &= ~X86_EFLAGS_TF;
|
|
|
}
|
|
|
si_code = get_si_code(tsk->thread.debugreg6);
|
|
|
- if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
|
|
|
+ if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
|
|
|
send_sigtrap(tsk, regs, error_code, si_code);
|
|
|
preempt_conditional_cli(regs);
|
|
|
|