1*49cdfc7eSAndroid Build Coastguard Worker #include <linux/kernel.h>
2*49cdfc7eSAndroid Build Coastguard Worker #include <linux/module.h>
3*49cdfc7eSAndroid Build Coastguard Worker #include <linux/fs.h>
4*49cdfc7eSAndroid Build Coastguard Worker #include <linux/uio.h>
5*49cdfc7eSAndroid Build Coastguard Worker #include <linux/kprobes.h>
6*49cdfc7eSAndroid Build Coastguard Worker
7*49cdfc7eSAndroid Build Coastguard Worker /*
8*49cdfc7eSAndroid Build Coastguard Worker * Jumper probe for do_fork.
9*49cdfc7eSAndroid Build Coastguard Worker * Mirror principle enables access to arguments of the probed routine
10*49cdfc7eSAndroid Build Coastguard Worker * from the probe handler.
11*49cdfc7eSAndroid Build Coastguard Worker */
12*49cdfc7eSAndroid Build Coastguard Worker
13*49cdfc7eSAndroid Build Coastguard Worker /* Proxy routine having the same arguments as actual do_fork() routine */
jdo_fork(unsigned long clone_flags,unsigned long stack_start,struct pt_regs * regs,unsigned long stack_size,int __user * parent_tidptr,int __user * child_tidptr)14*49cdfc7eSAndroid Build Coastguard Worker long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
15*49cdfc7eSAndroid Build Coastguard Worker struct pt_regs *regs, unsigned long stack_size,
16*49cdfc7eSAndroid Build Coastguard Worker int __user * parent_tidptr, int __user * child_tidptr)
17*49cdfc7eSAndroid Build Coastguard Worker {
18*49cdfc7eSAndroid Build Coastguard Worker printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=%p\n",
19*49cdfc7eSAndroid Build Coastguard Worker clone_flags, stack_size, regs);
20*49cdfc7eSAndroid Build Coastguard Worker /* Always end with a call to jprobe_return(). */
21*49cdfc7eSAndroid Build Coastguard Worker jprobe_return();
22*49cdfc7eSAndroid Build Coastguard Worker
23*49cdfc7eSAndroid Build Coastguard Worker return 0;
24*49cdfc7eSAndroid Build Coastguard Worker }
25*49cdfc7eSAndroid Build Coastguard Worker
26*49cdfc7eSAndroid Build Coastguard Worker static struct jprobe my_jprobe = {
27*49cdfc7eSAndroid Build Coastguard Worker .entry = jdo_fork
28*49cdfc7eSAndroid Build Coastguard Worker };
29*49cdfc7eSAndroid Build Coastguard Worker
jprobe_init(void)30*49cdfc7eSAndroid Build Coastguard Worker static int __init jprobe_init(void)
31*49cdfc7eSAndroid Build Coastguard Worker {
32*49cdfc7eSAndroid Build Coastguard Worker int ret;
33*49cdfc7eSAndroid Build Coastguard Worker my_jprobe.kp.symbol_name = "do_fork";
34*49cdfc7eSAndroid Build Coastguard Worker
35*49cdfc7eSAndroid Build Coastguard Worker if ((ret = register_jprobe(&my_jprobe)) < 0) {
36*49cdfc7eSAndroid Build Coastguard Worker printk("register_jprobe failed, returned %d\n", ret);
37*49cdfc7eSAndroid Build Coastguard Worker /* XXX: Exit code is wrong. */
38*49cdfc7eSAndroid Build Coastguard Worker return -1;
39*49cdfc7eSAndroid Build Coastguard Worker }
40*49cdfc7eSAndroid Build Coastguard Worker printk("Planted jprobe at %p, handler addr %p\n",
41*49cdfc7eSAndroid Build Coastguard Worker my_jprobe.kp.addr, my_jprobe.entry);
42*49cdfc7eSAndroid Build Coastguard Worker return 0;
43*49cdfc7eSAndroid Build Coastguard Worker }
44*49cdfc7eSAndroid Build Coastguard Worker
jprobe_exit(void)45*49cdfc7eSAndroid Build Coastguard Worker static void __exit jprobe_exit(void)
46*49cdfc7eSAndroid Build Coastguard Worker {
47*49cdfc7eSAndroid Build Coastguard Worker unregister_jprobe(&my_jprobe);
48*49cdfc7eSAndroid Build Coastguard Worker printk("jprobe unregistered\n");
49*49cdfc7eSAndroid Build Coastguard Worker }
50*49cdfc7eSAndroid Build Coastguard Worker
51*49cdfc7eSAndroid Build Coastguard Worker module_init(jprobe_init)
52*49cdfc7eSAndroid Build Coastguard Worker module_exit(jprobe_exit)
53*49cdfc7eSAndroid Build Coastguard Worker MODULE_LICENSE("GPL");
54