1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2019 Facebook
3
4#include <linux/bpf.h>
5#include <stdint.h>
6#include <stdbool.h>
7#include <bpf/bpf_helpers.h>
8#include <bpf/bpf_core_read.h>
9
10char _license[] SEC("license") = "GPL";
11
12struct {
13	char in[256];
14	char out[256];
15	bool skip;
16	uint64_t my_pid_tgid;
17} data = {};
18
19struct core_reloc_kernel_output {
20	int valid[10];
21	/* we have test_progs[-flavor], so cut flavor part */
22	char comm[sizeof("test_progs")];
23	int comm_len;
24};
25
26struct task_struct {
27	int pid;
28	int tgid;
29	char comm[16];
30	struct task_struct *group_leader;
31};
32
33#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src)
34
35SEC("raw_tracepoint/sys_enter")
36int test_core_kernel(void *ctx)
37{
38	struct task_struct *task = (void *)bpf_get_current_task();
39	struct core_reloc_kernel_output *out = (void *)&data.out;
40	uint64_t pid_tgid = bpf_get_current_pid_tgid();
41	uint32_t real_tgid = (uint32_t)pid_tgid;
42	int pid, tgid;
43
44	if (data.my_pid_tgid != pid_tgid)
45		return 0;
46
47	if (CORE_READ(&pid, &task->pid) ||
48	    CORE_READ(&tgid, &task->tgid))
49		return 1;
50
51	/* validate pid + tgid matches */
52	out->valid[0] = (((uint64_t)pid << 32) | tgid) == pid_tgid;
53
54	/* test variadic BPF_CORE_READ macros */
55	out->valid[1] = BPF_CORE_READ(task,
56				      tgid) == real_tgid;
57	out->valid[2] = BPF_CORE_READ(task,
58				      group_leader,
59				      tgid) == real_tgid;
60	out->valid[3] = BPF_CORE_READ(task,
61				      group_leader, group_leader,
62				      tgid) == real_tgid;
63	out->valid[4] = BPF_CORE_READ(task,
64				      group_leader, group_leader, group_leader,
65				      tgid) == real_tgid;
66	out->valid[5] = BPF_CORE_READ(task,
67				      group_leader, group_leader, group_leader,
68				      group_leader,
69				      tgid) == real_tgid;
70	out->valid[6] = BPF_CORE_READ(task,
71				      group_leader, group_leader, group_leader,
72				      group_leader, group_leader,
73				      tgid) == real_tgid;
74	out->valid[7] = BPF_CORE_READ(task,
75				      group_leader, group_leader, group_leader,
76				      group_leader, group_leader, group_leader,
77				      tgid) == real_tgid;
78	out->valid[8] = BPF_CORE_READ(task,
79				      group_leader, group_leader, group_leader,
80				      group_leader, group_leader, group_leader,
81				      group_leader,
82				      tgid) == real_tgid;
83	out->valid[9] = BPF_CORE_READ(task,
84				      group_leader, group_leader, group_leader,
85				      group_leader, group_leader, group_leader,
86				      group_leader, group_leader,
87				      tgid) == real_tgid;
88
89	/* test BPF_CORE_READ_STR_INTO() returns correct code and contents */
90	out->comm_len = BPF_CORE_READ_STR_INTO(
91		&out->comm, task,
92		group_leader, group_leader, group_leader, group_leader,
93		group_leader, group_leader, group_leader, group_leader,
94		comm);
95
96	return 0;
97}
98
99