Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Here's a sample kernel module showing the use of kprobes to dump a
0004  * stack trace and selected registers when kernel_clone() is called.
0005  *
0006  * For more information on theory of operation of kprobes, see
0007  * Documentation/trace/kprobes.rst
0008  *
0009  * You will see the trace data in /var/log/messages and on the console
0010  * whenever kernel_clone() is invoked to create a new process.
0011  */
0012 
0013 #define pr_fmt(fmt) "%s: " fmt, __func__
0014 
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/kprobes.h>
0018 
0019 static char symbol[KSYM_NAME_LEN] = "kernel_clone";
0020 module_param_string(symbol, symbol, KSYM_NAME_LEN, 0644);
0021 
0022 /* For each probe you need to allocate a kprobe structure */
0023 static struct kprobe kp = {
0024     .symbol_name    = symbol,
0025 };
0026 
0027 /* kprobe pre_handler: called just before the probed instruction is executed */
0028 static int __kprobes handler_pre(struct kprobe *p, struct pt_regs *regs)
0029 {
0030 #ifdef CONFIG_X86
0031     pr_info("<%s> p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
0032         p->symbol_name, p->addr, regs->ip, regs->flags);
0033 #endif
0034 #ifdef CONFIG_PPC
0035     pr_info("<%s> p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
0036         p->symbol_name, p->addr, regs->nip, regs->msr);
0037 #endif
0038 #ifdef CONFIG_MIPS
0039     pr_info("<%s> p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
0040         p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
0041 #endif
0042 #ifdef CONFIG_ARM64
0043     pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, pstate = 0x%lx\n",
0044         p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
0045 #endif
0046 #ifdef CONFIG_ARM
0047     pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, cpsr = 0x%lx\n",
0048         p->symbol_name, p->addr, (long)regs->ARM_pc, (long)regs->ARM_cpsr);
0049 #endif
0050 #ifdef CONFIG_RISCV
0051     pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, status = 0x%lx\n",
0052         p->symbol_name, p->addr, regs->epc, regs->status);
0053 #endif
0054 #ifdef CONFIG_S390
0055     pr_info("<%s> p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",
0056         p->symbol_name, p->addr, regs->psw.addr, regs->flags);
0057 #endif
0058 
0059     /* A dump_stack() here will give a stack backtrace */
0060     return 0;
0061 }
0062 
0063 /* kprobe post_handler: called after the probed instruction is executed */
0064 static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs,
0065                 unsigned long flags)
0066 {
0067 #ifdef CONFIG_X86
0068     pr_info("<%s> p->addr = 0x%p, flags = 0x%lx\n",
0069         p->symbol_name, p->addr, regs->flags);
0070 #endif
0071 #ifdef CONFIG_PPC
0072     pr_info("<%s> p->addr = 0x%p, msr = 0x%lx\n",
0073         p->symbol_name, p->addr, regs->msr);
0074 #endif
0075 #ifdef CONFIG_MIPS
0076     pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
0077         p->symbol_name, p->addr, regs->cp0_status);
0078 #endif
0079 #ifdef CONFIG_ARM64
0080     pr_info("<%s> p->addr = 0x%p, pstate = 0x%lx\n",
0081         p->symbol_name, p->addr, (long)regs->pstate);
0082 #endif
0083 #ifdef CONFIG_ARM
0084     pr_info("<%s> p->addr = 0x%p, cpsr = 0x%lx\n",
0085         p->symbol_name, p->addr, (long)regs->ARM_cpsr);
0086 #endif
0087 #ifdef CONFIG_RISCV
0088     pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
0089         p->symbol_name, p->addr, regs->status);
0090 #endif
0091 #ifdef CONFIG_S390
0092     pr_info("<%s> p->addr, 0x%p, flags = 0x%lx\n",
0093         p->symbol_name, p->addr, regs->flags);
0094 #endif
0095 }
0096 
0097 static int __init kprobe_init(void)
0098 {
0099     int ret;
0100     kp.pre_handler = handler_pre;
0101     kp.post_handler = handler_post;
0102 
0103     ret = register_kprobe(&kp);
0104     if (ret < 0) {
0105         pr_err("register_kprobe failed, returned %d\n", ret);
0106         return ret;
0107     }
0108     pr_info("Planted kprobe at %p\n", kp.addr);
0109     return 0;
0110 }
0111 
0112 static void __exit kprobe_exit(void)
0113 {
0114     unregister_kprobe(&kp);
0115     pr_info("kprobe at %p unregistered\n", kp.addr);
0116 }
0117 
0118 module_init(kprobe_init)
0119 module_exit(kprobe_exit)
0120 MODULE_LICENSE("GPL");