1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (c) 2020 Facebook */ |
3 | |
4 | #include "vmlinux.h" |
5 | #include <bpf/bpf_helpers.h> |
6 | #include <bpf/bpf_core_read.h> |
7 | #include <bpf/bpf_tracing.h> |
8 | |
9 | char _license[] SEC("license" ) = "GPL" ; |
10 | |
11 | struct bpf_testmod_test_read_ctx { |
12 | /* field order is mixed up */ |
13 | size_t len; |
14 | char *buf; |
15 | loff_t off; |
16 | } __attribute__((preserve_access_index)); |
17 | |
18 | struct { |
19 | char in[256]; |
20 | char out[256]; |
21 | bool skip; |
22 | uint64_t my_pid_tgid; |
23 | } data = {}; |
24 | |
25 | struct core_reloc_module_output { |
26 | long long len; |
27 | long long off; |
28 | int read_ctx_sz; |
29 | bool read_ctx_exists; |
30 | bool buf_exists; |
31 | bool len_exists; |
32 | bool off_exists; |
33 | /* we have test_progs[-flavor], so cut flavor part */ |
34 | char comm[sizeof("test_progs" )]; |
35 | int comm_len; |
36 | }; |
37 | |
38 | SEC("raw_tp/bpf_testmod_test_read" ) |
39 | int BPF_PROG(test_core_module_probed, |
40 | struct task_struct *task, |
41 | struct bpf_testmod_test_read_ctx *read_ctx) |
42 | { |
43 | #if __has_builtin(__builtin_preserve_enum_value) |
44 | struct core_reloc_module_output *out = (void *)&data.out; |
45 | __u64 pid_tgid = bpf_get_current_pid_tgid(); |
46 | __s32 real_tgid = (__s32)(pid_tgid >> 32); |
47 | __s32 real_pid = (__s32)pid_tgid; |
48 | |
49 | if (data.my_pid_tgid != pid_tgid) |
50 | return 0; |
51 | |
52 | if (BPF_CORE_READ(task, pid) != real_pid || BPF_CORE_READ(task, tgid) != real_tgid) |
53 | return 0; |
54 | |
55 | out->len = BPF_CORE_READ(read_ctx, len); |
56 | out->off = BPF_CORE_READ(read_ctx, off); |
57 | |
58 | out->read_ctx_sz = bpf_core_type_size(struct bpf_testmod_test_read_ctx); |
59 | out->read_ctx_exists = bpf_core_type_exists(struct bpf_testmod_test_read_ctx); |
60 | out->buf_exists = bpf_core_field_exists(read_ctx->buf); |
61 | out->off_exists = bpf_core_field_exists(read_ctx->off); |
62 | out->len_exists = bpf_core_field_exists(read_ctx->len); |
63 | |
64 | out->comm_len = BPF_CORE_READ_STR_INTO(&out->comm, task, comm); |
65 | #else |
66 | data.skip = true; |
67 | #endif |
68 | |
69 | return 0; |
70 | } |
71 | |
72 | SEC("tp_btf/bpf_testmod_test_read" ) |
73 | int BPF_PROG(test_core_module_direct, |
74 | struct task_struct *task, |
75 | struct bpf_testmod_test_read_ctx *read_ctx) |
76 | { |
77 | #if __has_builtin(__builtin_preserve_enum_value) |
78 | struct core_reloc_module_output *out = (void *)&data.out; |
79 | __u64 pid_tgid = bpf_get_current_pid_tgid(); |
80 | __s32 real_tgid = (__s32)(pid_tgid >> 32); |
81 | __s32 real_pid = (__s32)pid_tgid; |
82 | |
83 | if (data.my_pid_tgid != pid_tgid) |
84 | return 0; |
85 | |
86 | if (task->pid != real_pid || task->tgid != real_tgid) |
87 | return 0; |
88 | |
89 | out->len = read_ctx->len; |
90 | out->off = read_ctx->off; |
91 | |
92 | out->read_ctx_sz = bpf_core_type_size(struct bpf_testmod_test_read_ctx); |
93 | out->read_ctx_exists = bpf_core_type_exists(struct bpf_testmod_test_read_ctx); |
94 | out->buf_exists = bpf_core_field_exists(read_ctx->buf); |
95 | out->off_exists = bpf_core_field_exists(read_ctx->off); |
96 | out->len_exists = bpf_core_field_exists(read_ctx->len); |
97 | |
98 | out->comm_len = BPF_CORE_READ_STR_INTO(&out->comm, task, comm); |
99 | #else |
100 | data.skip = true; |
101 | #endif |
102 | |
103 | return 0; |
104 | } |
105 | |