1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Here's a sample kernel module showing the use of kprobes to dump a 4 * stack trace and selected registers when kernel_clone() is called. 5 * 6 * For more information on theory of operation of kprobes, see 7 * Documentation/trace/kprobes.rst 8 * 9 * You will see the trace data in /var/log/messages and on the console 10 * whenever kernel_clone() is invoked to create a new process. 11 */ 12 13 #define pr_fmt(fmt) "%s: " fmt, __func__ 14 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/kprobes.h> 18 19 #define MAX_SYMBOL_LEN 64 20 static char symbol[MAX_SYMBOL_LEN] = "kernel_clone"; 21 module_param_string(symbol, symbol, sizeof(symbol), 0644); 22 23 /* For each probe you need to allocate a kprobe structure */ 24 static struct kprobe kp = { 25 .symbol_name = symbol, 26 }; 27 28 /* kprobe pre_handler: called just before the probed instruction is executed */ 29 static int __kprobes handler_pre(struct kprobe *p, struct pt_regs *regs) 30 { 31 #ifdef CONFIG_X86 32 pr_info("<%s> p->addr = 0x%p, ip = %lx, flags = 0x%lx\n", 33 p->symbol_name, p->addr, regs->ip, regs->flags); 34 #endif 35 #ifdef CONFIG_PPC 36 pr_info("<%s> p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n", 37 p->symbol_name, p->addr, regs->nip, regs->msr); 38 #endif 39 #ifdef CONFIG_MIPS 40 pr_info("<%s> p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n", 41 p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status); 42 #endif 43 #ifdef CONFIG_ARM64 44 pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, pstate = 0x%lx\n", 45 p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate); 46 #endif 47 #ifdef CONFIG_ARM 48 pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, cpsr = 0x%lx\n", 49 p->symbol_name, p->addr, (long)regs->ARM_pc, (long)regs->ARM_cpsr); 50 #endif 51 #ifdef CONFIG_RISCV 52 pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, status = 0x%lx\n", 53 p->symbol_name, p->addr, regs->epc, regs->status); 54 #endif 55 #ifdef CONFIG_S390 56 pr_info("<%s> p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n", 57 p->symbol_name, p->addr, regs->psw.addr, regs->flags); 58 #endif 59 60 /* A dump_stack() here will give a stack backtrace */ 61 return 0; 62 } 63 64 /* kprobe post_handler: called after the probed instruction is executed */ 65 static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs, 66 unsigned long flags) 67 { 68 #ifdef CONFIG_X86 69 pr_info("<%s> p->addr = 0x%p, flags = 0x%lx\n", 70 p->symbol_name, p->addr, regs->flags); 71 #endif 72 #ifdef CONFIG_PPC 73 pr_info("<%s> p->addr = 0x%p, msr = 0x%lx\n", 74 p->symbol_name, p->addr, regs->msr); 75 #endif 76 #ifdef CONFIG_MIPS 77 pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n", 78 p->symbol_name, p->addr, regs->cp0_status); 79 #endif 80 #ifdef CONFIG_ARM64 81 pr_info("<%s> p->addr = 0x%p, pstate = 0x%lx\n", 82 p->symbol_name, p->addr, (long)regs->pstate); 83 #endif 84 #ifdef CONFIG_ARM 85 pr_info("<%s> p->addr = 0x%p, cpsr = 0x%lx\n", 86 p->symbol_name, p->addr, (long)regs->ARM_cpsr); 87 #endif 88 #ifdef CONFIG_RISCV 89 pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n", 90 p->symbol_name, p->addr, regs->status); 91 #endif 92 #ifdef CONFIG_S390 93 pr_info("<%s> p->addr, 0x%p, flags = 0x%lx\n", 94 p->symbol_name, p->addr, regs->flags); 95 #endif 96 } 97 98 /* 99 * fault_handler: this is called if an exception is generated for any 100 * instruction within the pre- or post-handler, or when Kprobes 101 * single-steps the probed instruction. 102 */ 103 static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) 104 { 105 pr_info("p->addr = 0x%p, trap #%d\n", p->addr, trapnr); 106 /* Return 0 because we don't handle the fault. */ 107 return 0; 108 } 109 /* NOKPROBE_SYMBOL() is also available */ 110 NOKPROBE_SYMBOL(handler_fault); 111 112 static int __init kprobe_init(void) 113 { 114 int ret; 115 kp.pre_handler = handler_pre; 116 kp.post_handler = handler_post; 117 kp.fault_handler = handler_fault; 118 119 ret = register_kprobe(&kp); 120 if (ret < 0) { 121 pr_err("register_kprobe failed, returned %d\n", ret); 122 return ret; 123 } 124 pr_info("Planted kprobe at %p\n", kp.addr); 125 return 0; 126 } 127 128 static void __exit kprobe_exit(void) 129 { 130 unregister_kprobe(&kp); 131 pr_info("kprobe at %p unregistered\n", kp.addr); 132 } 133 134 module_init(kprobe_init) 135 module_exit(kprobe_exit) 136 MODULE_LICENSE("GPL"); 137