kprobe_example.c (3532B)
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 20static char symbol[MAX_SYMBOL_LEN] = "kernel_clone"; 21module_param_string(symbol, symbol, sizeof(symbol), 0644); 22 23/* For each probe you need to allocate a kprobe structure */ 24static struct kprobe kp = { 25 .symbol_name = symbol, 26}; 27 28/* kprobe pre_handler: called just before the probed instruction is executed */ 29static 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 */ 65static 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 98static int __init kprobe_init(void) 99{ 100 int ret; 101 kp.pre_handler = handler_pre; 102 kp.post_handler = handler_post; 103 104 ret = register_kprobe(&kp); 105 if (ret < 0) { 106 pr_err("register_kprobe failed, returned %d\n", ret); 107 return ret; 108 } 109 pr_info("Planted kprobe at %p\n", kp.addr); 110 return 0; 111} 112 113static void __exit kprobe_exit(void) 114{ 115 unregister_kprobe(&kp); 116 pr_info("kprobe at %p unregistered\n", kp.addr); 117} 118 119module_init(kprobe_init) 120module_exit(kprobe_exit) 121MODULE_LICENSE("GPL");