Skip to content

Commit 2326c77

Browse files
bibo,maoLinus Torvalds
authored andcommitted
[PATCH] kprobe handler: discard user space trap
Currently kprobe handler traps only happen in kernel space, so function kprobe_exceptions_notify should skip traps which happen in user space. This patch modifies this, and it is based on 2.6.16-rc4. Signed-off-by: bibo mao <[email protected]> Cc: Ananth N Mavinakayanahalli <[email protected]> Cc: "Keshavamurthy, Anil S" <[email protected]> Cc: <[email protected]> Signed-off-by: Prasanna S Panchamukhi <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent c6fd91f commit 2326c77

File tree

5 files changed

+18
-13
lines changed

5 files changed

+18
-13
lines changed

arch/i386/kernel/kprobes.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -203,31 +203,21 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
203203
{
204204
struct kprobe *p;
205205
int ret = 0;
206-
kprobe_opcode_t *addr = NULL;
207-
unsigned long *lp;
206+
kprobe_opcode_t *addr;
208207
struct kprobe_ctlblk *kcb;
209208
#ifdef CONFIG_PREEMPT
210209
unsigned pre_preempt_count = preempt_count();
211210
#endif /* CONFIG_PREEMPT */
212211

212+
addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
213+
213214
/*
214215
* We don't want to be preempted for the entire
215216
* duration of kprobe processing
216217
*/
217218
preempt_disable();
218219
kcb = get_kprobe_ctlblk();
219220

220-
/* Check if the application is using LDT entry for its code segment and
221-
* calculate the address by reading the base address from the LDT entry.
222-
*/
223-
if ((regs->xcs & 4) && (current->mm)) {
224-
lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8)
225-
+ (char *) current->mm->context.ldt);
226-
addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip -
227-
sizeof(kprobe_opcode_t));
228-
} else {
229-
addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
230-
}
231221
/* Check we're not actually recursing */
232222
if (kprobe_running()) {
233223
p = get_kprobe(addr);
@@ -579,6 +569,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
579569
struct die_args *args = (struct die_args *)data;
580570
int ret = NOTIFY_DONE;
581571

572+
if (args->regs && user_mode(args->regs))
573+
return ret;
574+
582575
switch (val) {
583576
case DIE_INT3:
584577
if (kprobe_handler(args->regs))

arch/ia64/kernel/kprobes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
740740
struct die_args *args = (struct die_args *)data;
741741
int ret = NOTIFY_DONE;
742742

743+
if (args->regs && user_mode(args->regs))
744+
return ret;
745+
743746
switch(val) {
744747
case DIE_BREAK:
745748
/* err is break number from ia64_bad_break() */

arch/powerpc/kernel/kprobes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
396396
struct die_args *args = (struct die_args *)data;
397397
int ret = NOTIFY_DONE;
398398

399+
if (args->regs && user_mode(args->regs))
400+
return ret;
401+
399402
switch (val) {
400403
case DIE_BPT:
401404
if (kprobe_handler(args->regs))

arch/sparc64/kernel/kprobes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
324324
struct die_args *args = (struct die_args *)data;
325325
int ret = NOTIFY_DONE;
326326

327+
if (args->regs && user_mode(args->regs))
328+
return ret;
329+
327330
switch (val) {
328331
case DIE_DEBUG:
329332
if (kprobe_handler(args->regs))

arch/x86_64/kernel/kprobes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
601601
struct die_args *args = (struct die_args *)data;
602602
int ret = NOTIFY_DONE;
603603

604+
if (args->regs && user_mode(args->regs))
605+
return ret;
606+
604607
switch (val) {
605608
case DIE_INT3:
606609
if (kprobe_handler(args->regs))

0 commit comments

Comments
 (0)