aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/kprobes.c19
-rw-r--r--arch/ia64/kernel/kprobes.c3
-rw-r--r--arch/powerpc/kernel/kprobes.c3
-rw-r--r--arch/sparc64/kernel/kprobes.c3
-rw-r--r--arch/x86_64/kernel/kprobes.c3
5 files changed, 18 insertions, 13 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index acdcc640a72a..df1b346d36ff 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -203,13 +203,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
203{ 203{
204 struct kprobe *p; 204 struct kprobe *p;
205 int ret = 0; 205 int ret = 0;
206 kprobe_opcode_t *addr = NULL; 206 kprobe_opcode_t *addr;
207 unsigned long *lp;
208 struct kprobe_ctlblk *kcb; 207 struct kprobe_ctlblk *kcb;
209#ifdef CONFIG_PREEMPT 208#ifdef CONFIG_PREEMPT
210 unsigned pre_preempt_count = preempt_count(); 209 unsigned pre_preempt_count = preempt_count();
211#endif /* CONFIG_PREEMPT */ 210#endif /* CONFIG_PREEMPT */
212 211
212 addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
213
213 /* 214 /*
214 * We don't want to be preempted for the entire 215 * We don't want to be preempted for the entire
215 * duration of kprobe processing 216 * duration of kprobe processing
@@ -217,17 +218,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
217 preempt_disable(); 218 preempt_disable();
218 kcb = get_kprobe_ctlblk(); 219 kcb = get_kprobe_ctlblk();
219 220
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 }
231 /* Check we're not actually recursing */ 221 /* Check we're not actually recursing */
232 if (kprobe_running()) { 222 if (kprobe_running()) {
233 p = get_kprobe(addr); 223 p = get_kprobe(addr);
@@ -579,6 +569,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
579 struct die_args *args = (struct die_args *)data; 569 struct die_args *args = (struct die_args *)data;
580 int ret = NOTIFY_DONE; 570 int ret = NOTIFY_DONE;
581 571
572 if (args->regs && user_mode(args->regs))
573 return ret;
574
582 switch (val) { 575 switch (val) {
583 case DIE_INT3: 576 case DIE_INT3:
584 if (kprobe_handler(args->regs)) 577 if (kprobe_handler(args->regs))
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 50ae8c7d453d..45b8479c9864 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -740,6 +740,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
740 struct die_args *args = (struct die_args *)data; 740 struct die_args *args = (struct die_args *)data;
741 int ret = NOTIFY_DONE; 741 int ret = NOTIFY_DONE;
742 742
743 if (args->regs && user_mode(args->regs))
744 return ret;
745
743 switch(val) { 746 switch(val) {
744 case DIE_BREAK: 747 case DIE_BREAK:
745 /* err is break number from ia64_bad_break() */ 748 /* err is break number from ia64_bad_break() */
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index cb1fe5878e8b..aea25dd18dae 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -396,6 +396,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
396 struct die_args *args = (struct die_args *)data; 396 struct die_args *args = (struct die_args *)data;
397 int ret = NOTIFY_DONE; 397 int ret = NOTIFY_DONE;
398 398
399 if (args->regs && user_mode(args->regs))
400 return ret;
401
399 switch (val) { 402 switch (val) {
400 case DIE_BPT: 403 case DIE_BPT:
401 if (kprobe_handler(args->regs)) 404 if (kprobe_handler(args->regs))
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index b9a9ce70e55c..d91c31870ac8 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -324,6 +324,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
324 struct die_args *args = (struct die_args *)data; 324 struct die_args *args = (struct die_args *)data;
325 int ret = NOTIFY_DONE; 325 int ret = NOTIFY_DONE;
326 326
327 if (args->regs && user_mode(args->regs))
328 return ret;
329
327 switch (val) { 330 switch (val) {
328 case DIE_DEBUG: 331 case DIE_DEBUG:
329 if (kprobe_handler(args->regs)) 332 if (kprobe_handler(args->regs))
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 14f0ced613b6..218e015c3195 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -601,6 +601,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
601 struct die_args *args = (struct die_args *)data; 601 struct die_args *args = (struct die_args *)data;
602 int ret = NOTIFY_DONE; 602 int ret = NOTIFY_DONE;
603 603
604 if (args->regs && user_mode(args->regs))
605 return ret;
606
604 switch (val) { 607 switch (val) {
605 case DIE_INT3: 608 case DIE_INT3:
606 if (kprobe_handler(args->regs)) 609 if (kprobe_handler(args->regs))