Skip to content

Commit 3d4e0c0

Browse files
committed
kprobe: update example with px
Going to try and upstream this later on
1 parent 046bc25 commit 3d4e0c0

File tree

3 files changed

+35
-33
lines changed

3 files changed

+35
-33
lines changed

README.adoc

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4405,26 +4405,38 @@ TODO: can you get function arguments? https://stackoverflow.com/questions/276087
44054405

44064406
==== Kprobes
44074407

4408+
kprobes is an instrumentation mechanism that injects arbitrary code at a given address in a trap instruction, much like GDB. Oh, the good old kernel. :-)
4409+
44084410
....
44094411
./build -C 'CONFIG_KPROBES=y'
4410-
./run -F 'insmod /kprobe_example.ko && sleep 4 & sleep 4 &'
4412+
....
4413+
4414+
Then on guest:
4415+
4416+
....
4417+
insmod /kprobe_example.ko
4418+
sleep 4 & sleep 4 &'
4419+
....
4420+
4421+
Outcome: dmesg outputs on every fork:
4422+
4423+
....
4424+
<_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
4425+
<_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
4426+
<_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
4427+
<_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
44114428
....
44124429

44134430
Source: link:kernel_module/kprobe_example.c[]
44144431

4415-
Outcome: every fork spits out some extra printks of type:
4432+
TODO: it does not work if I try to immediately launch `sleep`, why?
44164433

44174434
....
4418-
<6>[ 2.011117] <_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
4419-
<6>[ 2.011622] <_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
4420-
<6>[ 2.021860] <_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
4421-
<6>[ 2.022331] <_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
4435+
insmod /kprobe_example.ko && sleep 4 & sleep 4 &
44224436
....
44234437

44244438
Docs: https://github.com/torvalds/linux/blob/v4.16/Documentation/kprobes.txt
44254439

4426-
Injects arbitrary code at a given address in a trap instruction, much like GDB. Oh the good old kernel. :-)
4427-
44284440
I don't think your code can refer to the surrounding kernel code however: the only visible thing is the value of the registers.
44294441

44304442
You can then hack it up to read the stack and read argument values, but do you really want to?

kernel_module/kprobe_example.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* Upstream: https://github.com/torvalds/linux/blob/v4.16/samples/kprobes/kprobe_example.c */
2-
31
/*
42
* NOTE: This example is works on x86 and powerpc.
53
* Here's a sample kernel module showing the use of kprobes to dump a
@@ -29,28 +27,24 @@ static struct kprobe kp = {
2927
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
3028
{
3129
#ifdef CONFIG_X86
32-
pr_info("<%s> pre_handler: p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
30+
pr_info("<%s> pre_handler: p->addr = 0x%px, ip = %lx, flags = 0x%lx\n",
3331
p->symbol_name, p->addr, regs->ip, regs->flags);
3432
#endif
3533
#ifdef CONFIG_PPC
36-
pr_info("<%s> pre_handler: p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
34+
pr_info("<%s> pre_handler: p->addr = 0x%px, nip = 0x%lx, msr = 0x%lx\n",
3735
p->symbol_name, p->addr, regs->nip, regs->msr);
3836
#endif
3937
#ifdef CONFIG_MIPS
40-
pr_info("<%s> pre_handler: p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
38+
pr_info("<%s> pre_handler: p->addr = 0x%px, epc = 0x%lx, status = 0x%lx\n",
4139
p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
4240
#endif
43-
#ifdef CONFIG_TILEGX
44-
pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx, ex1 = 0x%lx\n",
45-
p->symbol_name, p->addr, regs->pc, regs->ex1);
46-
#endif
4741
#ifdef CONFIG_ARM64
48-
pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx,"
42+
pr_info("<%s> pre_handler: p->addr = 0x%px, pc = 0x%lx,"
4943
" pstate = 0x%lx\n",
5044
p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
5145
#endif
5246
#ifdef CONFIG_S390
53-
pr_info("<%s> pre_handler: p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",
47+
pr_info("<%s> pre_handler: p->addr, 0x%px, ip = 0x%lx, flags = 0x%lx\n",
5448
p->symbol_name, p->addr, regs->psw.addr, regs->flags);
5549
#endif
5650

@@ -63,27 +57,23 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
6357
unsigned long flags)
6458
{
6559
#ifdef CONFIG_X86
66-
pr_info("<%s> post_handler: p->addr = 0x%p, flags = 0x%lx\n",
60+
pr_info("<%s> post_handler: p->addr = 0x%px, flags = 0x%lx\n",
6761
p->symbol_name, p->addr, regs->flags);
6862
#endif
6963
#ifdef CONFIG_PPC
70-
pr_info("<%s> post_handler: p->addr = 0x%p, msr = 0x%lx\n",
64+
pr_info("<%s> post_handler: p->addr = 0x%px, msr = 0x%lx\n",
7165
p->symbol_name, p->addr, regs->msr);
7266
#endif
7367
#ifdef CONFIG_MIPS
74-
pr_info("<%s> post_handler: p->addr = 0x%p, status = 0x%lx\n",
68+
pr_info("<%s> post_handler: p->addr = 0x%px, status = 0x%lx\n",
7569
p->symbol_name, p->addr, regs->cp0_status);
7670
#endif
77-
#ifdef CONFIG_TILEGX
78-
pr_info("<%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx\n",
79-
p->symbol_name, p->addr, regs->ex1);
80-
#endif
8171
#ifdef CONFIG_ARM64
82-
pr_info("<%s> post_handler: p->addr = 0x%p, pstate = 0x%lx\n",
72+
pr_info("<%s> post_handler: p->addr = 0x%px, pstate = 0x%lx\n",
8373
p->symbol_name, p->addr, (long)regs->pstate);
8474
#endif
8575
#ifdef CONFIG_S390
86-
pr_info("<%s> pre_handler: p->addr, 0x%p, flags = 0x%lx\n",
76+
pr_info("<%s> pre_handler: p->addr, 0x%px, flags = 0x%lx\n",
8777
p->symbol_name, p->addr, regs->flags);
8878
#endif
8979
}
@@ -95,7 +85,7 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
9585
*/
9686
static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
9787
{
98-
pr_info("fault_handler: p->addr = 0x%p, trap #%dn", p->addr, trapnr);
88+
pr_info("fault_handler: p->addr = 0x%px, trap #%dn", p->addr, trapnr);
9989
/* Return 0 because we don't handle the fault. */
10090
return 0;
10191
}
@@ -112,14 +102,14 @@ static int __init kprobe_init(void)
112102
pr_err("register_kprobe failed, returned %d\n", ret);
113103
return ret;
114104
}
115-
pr_info("Planted kprobe at %p\n", kp.addr);
105+
pr_info("Planted kprobe at %px\n", kp.addr);
116106
return 0;
117107
}
118108

119109
static void __exit kprobe_exit(void)
120110
{
121111
unregister_kprobe(&kp);
122-
pr_info("kprobe at %p unregistered\n", kp.addr);
112+
pr_info("kprobe at %px unregistered\n", kp.addr);
123113
}
124114

125115
module_init(kprobe_init)

kernel_module/pci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
207207

208208
/* RAM -> device. */
209209
vaddr_from = dma_alloc_coherent(&(dev->dev), 4, &dma_handle_from, GFP_ATOMIC);
210-
dev_info(&(dev->dev), "vaddr_from = %p\n", vaddr_from);
210+
dev_info(&(dev->dev), "vaddr_from = %px\n", vaddr_from);
211211
dev_info(&(dev->dev), "dma_handle_from = %llx\n", (unsigned long long)dma_handle_from);
212212
*((volatile u32*)vaddr_from) = 0x12345678;
213213
iowrite32((u32)dma_handle_from, mmio + IO_DMA_SRC);
@@ -217,7 +217,7 @@ static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
217217

218218
/* device -> RAM. */
219219
vaddr_to = dma_alloc_coherent(&(dev->dev), 4, &dma_handle_to, GFP_ATOMIC);
220-
dev_info(&(dev->dev), "vaddr_to = %p\n", vaddr_to);
220+
dev_info(&(dev->dev), "vaddr_to = %px\n", vaddr_to);
221221
dev_info(&(dev->dev), "dma_handle_to = %llx\n", (unsigned long long)dma_handle_to);
222222
/*
223223
iowrite32(DMA_BASE, mmio + IO_DMA_SRC);

0 commit comments

Comments
 (0)