kprobes: Remove kprobe::fault_handler
authorPeter Zijlstra <peterz@infradead.org>
Tue, 25 May 2021 07:25:19 +0000 (09:25 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Tue, 1 Jun 2021 14:00:08 +0000 (16:00 +0200)
The reason for kprobe::fault_handler(), as given by their comment:

 * We come here because instructions in the pre/post
 * handler caused the page_fault, this could happen
 * if handler tries to access user space by
 * copy_from_user(), get_user() etc. Let the
 * user-specified handler try to fix it first.

Is just plain bad. Those other handlers are ran from non-preemptible
context and had better use _nofault() functions. Also, there is no
upstream usage of this.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Link: https://lore.kernel.org/r/20210525073213.561116662@infradead.org
16 files changed:
Documentation/trace/kprobes.rst
arch/arc/kernel/kprobes.c
arch/arm/probes/kprobes/core.c
arch/arm64/kernel/probes/kprobes.c
arch/csky/kernel/probes/kprobes.c
arch/ia64/kernel/kprobes.c
arch/mips/kernel/kprobes.c
arch/powerpc/kernel/kprobes.c
arch/riscv/kernel/probes/kprobes.c
arch/s390/kernel/kprobes.c
arch/sh/kernel/kprobes.c
arch/sparc/kernel/kprobes.c
arch/x86/kernel/kprobes/core.c
include/linux/kprobes.h
kernel/kprobes.c
samples/kprobes/kprobe_example.c

index b757b6dfd3d4d42be2a55e4af54281c2a6731ec6..998149ce2fd9560f984f4ba1aa8362459bb45fad 100644 (file)
@@ -362,14 +362,11 @@ register_kprobe
        #include <linux/kprobes.h>
        int register_kprobe(struct kprobe *kp);
 
-Sets a breakpoint at the address kp->addr.  When the breakpoint is
-hit, Kprobes calls kp->pre_handler.  After the probed instruction
-is single-stepped, Kprobe calls kp->post_handler.  If a fault
-occurs during execution of kp->pre_handler or kp->post_handler,
-or during single-stepping of the probed instruction, Kprobes calls
-kp->fault_handler.  Any or all handlers can be NULL. If kp->flags
-is set KPROBE_FLAG_DISABLED, that kp will be registered but disabled,
-so, its handlers aren't hit until calling enable_kprobe(kp).
+Sets a breakpoint at the address kp->addr.  When the breakpoint is hit, Kprobes
+calls kp->pre_handler.  After the probed instruction is single-stepped, Kprobe
+calls kp->post_handler.  Any or all handlers can be NULL. If kp->flags is set
+KPROBE_FLAG_DISABLED, that kp will be registered but disabled, so, its handlers
+aren't hit until calling enable_kprobe(kp).
 
 .. note::
 
@@ -415,17 +412,6 @@ User's post-handler (kp->post_handler)::
 p and regs are as described for the pre_handler.  flags always seems
 to be zero.
 
-User's fault-handler (kp->fault_handler)::
-
-       #include <linux/kprobes.h>
-       #include <linux/ptrace.h>
-       int fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr);
-
-p and regs are as described for the pre_handler.  trapnr is the
-architecture-specific trap number associated with the fault (e.g.,
-on i386, 13 for a general protection fault or 14 for a page fault).
-Returns 1 if it successfully handled the exception.
-
 register_kretprobe
 ------------------
 
index cabef45f11df5a7f87369cd84c081a49655eae4b..9f5b39f387362e64a073ef6b859135e6bda180ee 100644 (file)
@@ -323,16 +323,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned long trapnr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned zero,
                 * try to fix up.
index a9653117ca0dd619365b4bf30fe332736c632f24..7b9b9a5a409bb8b44cbce7b2613f0c56022a2d60 100644 (file)
@@ -358,15 +358,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
-                       return 1;
                break;
 
        default:
index d607c9912025219469d1946b1ea6ac56128d8cc3..f6b088e9fa70e6da242721e9d1e363ef08ae71ce 100644 (file)
@@ -283,16 +283,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index 589f090f48b9933c8fdaf05c97e976c6a88a17c0..e0e973e49770375299ab557176ecb50c0287b33f 100644 (file)
@@ -301,16 +301,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index fc1ff8a4d7de6c0b6abf22bc4f4e97e9d47cb33a..6efed4ecff9e92f649057aaf54470cc997157b18 100644 (file)
@@ -850,15 +850,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index 54dfba8fa77c854303ae0176d4db66265d85d8b1..75bff0f7731981fbe780df18b561f0dcc2020db7 100644 (file)
@@ -403,9 +403,6 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-       if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-               return 1;
-
        if (kcb->kprobe_status & KPROBE_HIT_SS) {
                resume_execution(cur, regs, kcb);
                regs->cp0_status |= kcb->kprobe_old_SR;
index 01ab2163659e4bb7763c0f22ed13d36349e1c9b4..75b4e874269d4862d21836fe7f3823d1e3c2dac3 100644 (file)
@@ -508,16 +508,6 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index 10b965c345366a4341ba9089033a2ee1ec3f8058..923b5ea396eab36d35acadc7936001fdeb6e0ad7 100644 (file)
@@ -283,16 +283,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index aae24dc75df61bfed0c062822f60645bb783f380..ad631e33df24f3e89c07604029afca3c4c344829 100644 (file)
@@ -452,16 +452,6 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
                 */
                kprobes_inc_nmissed_count(p);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (p->fault_handler && p->fault_handler(p, regs, trapnr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index 756100b01e846130458a9860a8d38e72e32b2758..58263420ad2a5834665e74c116cf160f65fc51e8 100644 (file)
@@ -389,16 +389,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index 217c21a6986ad149f7dda13eb3a30debb07c3966..db4e341b4b6ea8b89338a2b202b9513769500dcb 100644 (file)
@@ -352,16 +352,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                 */
                kprobes_inc_nmissed_count(cur);
 
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
-
                /*
                 * In case the user-specified fault handler returned
                 * zero, try to fix up.
index d3d65545cb8b79555debd82996eaed42a83e6036..cfcdf4b8a306f34a1ead58935b0bd396db78b146 100644 (file)
@@ -1110,16 +1110,6 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                 * these specific fault cases.
                 */
                kprobes_inc_nmissed_count(cur);
-
-               /*
-                * We come here because instructions in the pre/post
-                * handler caused the page_fault, this could happen
-                * if handler tries to access user space by
-                * copy_from_user(), get_user() etc. Let the
-                * user-specified handler try to fix it first.
-                */
-               if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-                       return 1;
        }
 
        return 0;
index 1883a4a9f16a7fc70bf533cd2206d046c6722b14..523ffc7bc3a8b4c7a409aea361ce8b83af5afb54 100644 (file)
@@ -54,8 +54,6 @@ struct kretprobe_instance;
 typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *);
 typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *,
                                       unsigned long flags);
-typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *,
-                                      int trapnr);
 typedef int (*kretprobe_handler_t) (struct kretprobe_instance *,
                                    struct pt_regs *);
 
@@ -83,12 +81,6 @@ struct kprobe {
        /* Called after addr is executed, unless... */
        kprobe_post_handler_t post_handler;
 
-       /*
-        * ... called if executing addr causes a fault (eg. page fault).
-        * Return 1 if it handled fault, otherwise kernel will see it.
-        */
-       kprobe_fault_handler_t fault_handler;
-
        /* Saved opcode (which has been replaced with breakpoint) */
        kprobe_opcode_t opcode;
 
index 745f08fdd7a698ebd6f3a40da3cffedaa35497c6..e41385afe79dc5886b13cc005395b57fa9e668bc 100644 (file)
@@ -1183,23 +1183,6 @@ static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
 }
 NOKPROBE_SYMBOL(aggr_post_handler);
 
-static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
-                             int trapnr)
-{
-       struct kprobe *cur = __this_cpu_read(kprobe_instance);
-
-       /*
-        * if we faulted "during" the execution of a user specified
-        * probe handler, invoke just that probe's fault handler
-        */
-       if (cur && cur->fault_handler) {
-               if (cur->fault_handler(cur, regs, trapnr))
-                       return 1;
-       }
-       return 0;
-}
-NOKPROBE_SYMBOL(aggr_fault_handler);
-
 /* Walks the list and increments nmissed count for multiprobe case */
 void kprobes_inc_nmissed_count(struct kprobe *p)
 {
@@ -1330,7 +1313,6 @@ static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
        ap->addr = p->addr;
        ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
        ap->pre_handler = aggr_pre_handler;
-       ap->fault_handler = aggr_fault_handler;
        /* We don't care the kprobe which has gone. */
        if (p->post_handler && !kprobe_gone(p))
                ap->post_handler = aggr_post_handler;
@@ -2014,7 +1996,6 @@ int register_kretprobe(struct kretprobe *rp)
 
        rp->kp.pre_handler = pre_handler_kretprobe;
        rp->kp.post_handler = NULL;
-       rp->kp.fault_handler = NULL;
 
        /* Pre-allocate memory for max kretprobe instances */
        if (rp->maxactive <= 0) {
index c495664c0a9b3dbb7a58d8ba6f6b4ff122d4159c..4b2f318289517c62527f07482640ea731430535c 100644 (file)
@@ -94,26 +94,11 @@ static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs,
 #endif
 }
 
-/*
- * fault_handler: this is called if an exception is generated for any
- * instruction within the pre- or post-handler, or when Kprobes
- * single-steps the probed instruction.
- */
-static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
-{
-       pr_info("fault_handler: p->addr = 0x%p, trap #%dn", p->addr, trapnr);
-       /* Return 0 because we don't handle the fault. */
-       return 0;
-}
-/* NOKPROBE_SYMBOL() is also available */
-NOKPROBE_SYMBOL(handler_fault);
-
 static int __init kprobe_init(void)
 {
        int ret;
        kp.pre_handler = handler_pre;
        kp.post_handler = handler_post;
-       kp.fault_handler = handler_fault;
 
        ret = register_kprobe(&kp);
        if (ret < 0) {