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")
BPF_PROG(test_core_module_probed,struct task_struct * task,struct bpf_testmod_test_read_ctx * read_ctx)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 	__u32 real_tgid = (__u32)(pid_tgid >> 32);
47 	__u32 real_pid = (__u32)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")
BPF_PROG(test_core_module_direct,struct task_struct * task,struct bpf_testmod_test_read_ctx * read_ctx)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 	__u32 real_tgid = (__u32)(pid_tgid >> 32);
81 	__u32 real_pid = (__u32)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