1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | #include <vmlinux.h> |
4 | #include <bpf/bpf_tracing.h> |
5 | #include <bpf/bpf_helpers.h> |
6 | |
7 | struct map_elem { |
8 | struct bpf_timer timer; |
9 | struct bpf_spin_lock lock; |
10 | }; |
11 | |
12 | struct { |
13 | __uint(type, BPF_MAP_TYPE_ARRAY); |
14 | __uint(max_entries, 1); |
15 | __type(key, int); |
16 | __type(value, struct map_elem); |
17 | } amap SEC(".maps" ); |
18 | |
19 | struct { |
20 | __uint(type, BPF_MAP_TYPE_HASH); |
21 | __uint(max_entries, 1); |
22 | __type(key, int); |
23 | __type(value, struct map_elem); |
24 | } hmap SEC(".maps" ); |
25 | |
26 | int pid = 0; |
27 | int crash_map = 0; /* 0 for amap, 1 for hmap */ |
28 | |
29 | SEC("fentry/do_nanosleep" ) |
30 | int sys_enter(void *ctx) |
31 | { |
32 | struct map_elem *e, value = {}; |
33 | void *map = crash_map ? (void *)&hmap : (void *)&amap; |
34 | |
35 | if (bpf_get_current_task_btf()->tgid != pid) |
36 | return 0; |
37 | |
38 | *(void **)&value = (void *)0xdeadcaf3; |
39 | |
40 | bpf_map_update_elem(map, &(int){0}, &value, 0); |
41 | /* For array map, doing bpf_map_update_elem will do a |
42 | * check_and_free_timer_in_array, which will trigger the crash if timer |
43 | * pointer was overwritten, for hmap we need to use bpf_timer_cancel. |
44 | */ |
45 | if (crash_map == 1) { |
46 | e = bpf_map_lookup_elem(map, &(int){0}); |
47 | if (!e) |
48 | return 0; |
49 | bpf_timer_cancel(&e->timer); |
50 | } |
51 | return 0; |
52 | } |
53 | |
54 | char _license[] SEC("license" ) = "GPL" ; |
55 | |