xref: /aosp_15_r20/external/bcc/libbpf-tools/execsnoop.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2*387f9dfdSAndroid Build Coastguard Worker #include <vmlinux.h>
3*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_helpers.h>
4*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_core_read.h>
5*387f9dfdSAndroid Build Coastguard Worker #include "execsnoop.h"
6*387f9dfdSAndroid Build Coastguard Worker 
7*387f9dfdSAndroid Build Coastguard Worker const volatile bool filter_cg = false;
8*387f9dfdSAndroid Build Coastguard Worker const volatile bool ignore_failed = true;
9*387f9dfdSAndroid Build Coastguard Worker const volatile uid_t targ_uid = INVALID_UID;
10*387f9dfdSAndroid Build Coastguard Worker const volatile int max_args = DEFAULT_MAXARGS;
11*387f9dfdSAndroid Build Coastguard Worker 
12*387f9dfdSAndroid Build Coastguard Worker static const struct event empty_event = {};
13*387f9dfdSAndroid Build Coastguard Worker 
14*387f9dfdSAndroid Build Coastguard Worker struct {
15*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_CGROUP_ARRAY);
16*387f9dfdSAndroid Build Coastguard Worker 	__type(key, u32);
17*387f9dfdSAndroid Build Coastguard Worker 	__type(value, u32);
18*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, 1);
19*387f9dfdSAndroid Build Coastguard Worker } cgroup_map SEC(".maps");
20*387f9dfdSAndroid Build Coastguard Worker 
21*387f9dfdSAndroid Build Coastguard Worker struct {
22*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
23*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, 10240);
24*387f9dfdSAndroid Build Coastguard Worker 	__type(key, pid_t);
25*387f9dfdSAndroid Build Coastguard Worker 	__type(value, struct event);
26*387f9dfdSAndroid Build Coastguard Worker } execs SEC(".maps");
27*387f9dfdSAndroid Build Coastguard Worker 
28*387f9dfdSAndroid Build Coastguard Worker struct {
29*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
30*387f9dfdSAndroid Build Coastguard Worker 	__uint(key_size, sizeof(u32));
31*387f9dfdSAndroid Build Coastguard Worker 	__uint(value_size, sizeof(u32));
32*387f9dfdSAndroid Build Coastguard Worker } events SEC(".maps");
33*387f9dfdSAndroid Build Coastguard Worker 
valid_uid(uid_t uid)34*387f9dfdSAndroid Build Coastguard Worker static __always_inline bool valid_uid(uid_t uid) {
35*387f9dfdSAndroid Build Coastguard Worker 	return uid != INVALID_UID;
36*387f9dfdSAndroid Build Coastguard Worker }
37*387f9dfdSAndroid Build Coastguard Worker 
38*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/syscalls/sys_enter_execve")
tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter * ctx)39*387f9dfdSAndroid Build Coastguard Worker int tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter* ctx)
40*387f9dfdSAndroid Build Coastguard Worker {
41*387f9dfdSAndroid Build Coastguard Worker 	u64 id;
42*387f9dfdSAndroid Build Coastguard Worker 	pid_t pid, tgid;
43*387f9dfdSAndroid Build Coastguard Worker 	int ret;
44*387f9dfdSAndroid Build Coastguard Worker 	struct event *event;
45*387f9dfdSAndroid Build Coastguard Worker 	struct task_struct *task;
46*387f9dfdSAndroid Build Coastguard Worker 	const char **args = (const char **)(ctx->args[1]);
47*387f9dfdSAndroid Build Coastguard Worker 	const char *argp;
48*387f9dfdSAndroid Build Coastguard Worker 
49*387f9dfdSAndroid Build Coastguard Worker 	if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0))
50*387f9dfdSAndroid Build Coastguard Worker 		return 0;
51*387f9dfdSAndroid Build Coastguard Worker 
52*387f9dfdSAndroid Build Coastguard Worker 	uid_t uid = (u32)bpf_get_current_uid_gid();
53*387f9dfdSAndroid Build Coastguard Worker 	int i;
54*387f9dfdSAndroid Build Coastguard Worker 
55*387f9dfdSAndroid Build Coastguard Worker 	if (valid_uid(targ_uid) && targ_uid != uid)
56*387f9dfdSAndroid Build Coastguard Worker 		return 0;
57*387f9dfdSAndroid Build Coastguard Worker 
58*387f9dfdSAndroid Build Coastguard Worker 	id = bpf_get_current_pid_tgid();
59*387f9dfdSAndroid Build Coastguard Worker 	pid = (pid_t)id;
60*387f9dfdSAndroid Build Coastguard Worker 	tgid = id >> 32;
61*387f9dfdSAndroid Build Coastguard Worker 	if (bpf_map_update_elem(&execs, &pid, &empty_event, BPF_NOEXIST))
62*387f9dfdSAndroid Build Coastguard Worker 		return 0;
63*387f9dfdSAndroid Build Coastguard Worker 
64*387f9dfdSAndroid Build Coastguard Worker 	event = bpf_map_lookup_elem(&execs, &pid);
65*387f9dfdSAndroid Build Coastguard Worker 	if (!event)
66*387f9dfdSAndroid Build Coastguard Worker 		return 0;
67*387f9dfdSAndroid Build Coastguard Worker 
68*387f9dfdSAndroid Build Coastguard Worker 	event->pid = tgid;
69*387f9dfdSAndroid Build Coastguard Worker 	event->uid = uid;
70*387f9dfdSAndroid Build Coastguard Worker 	task = (struct task_struct*)bpf_get_current_task();
71*387f9dfdSAndroid Build Coastguard Worker 	event->ppid = (pid_t)BPF_CORE_READ(task, real_parent, tgid);
72*387f9dfdSAndroid Build Coastguard Worker 	event->args_count = 0;
73*387f9dfdSAndroid Build Coastguard Worker 	event->args_size = 0;
74*387f9dfdSAndroid Build Coastguard Worker 
75*387f9dfdSAndroid Build Coastguard Worker 	ret = bpf_probe_read_user_str(event->args, ARGSIZE, (const char*)ctx->args[0]);
76*387f9dfdSAndroid Build Coastguard Worker 	if (ret < 0) {
77*387f9dfdSAndroid Build Coastguard Worker 		return 0;
78*387f9dfdSAndroid Build Coastguard Worker 	}
79*387f9dfdSAndroid Build Coastguard Worker 	if (ret <= ARGSIZE) {
80*387f9dfdSAndroid Build Coastguard Worker 		event->args_size += ret;
81*387f9dfdSAndroid Build Coastguard Worker 	} else {
82*387f9dfdSAndroid Build Coastguard Worker 		/* write an empty string */
83*387f9dfdSAndroid Build Coastguard Worker 		event->args[0] = '\0';
84*387f9dfdSAndroid Build Coastguard Worker 		event->args_size++;
85*387f9dfdSAndroid Build Coastguard Worker 	}
86*387f9dfdSAndroid Build Coastguard Worker 
87*387f9dfdSAndroid Build Coastguard Worker 	event->args_count++;
88*387f9dfdSAndroid Build Coastguard Worker 	#pragma unroll
89*387f9dfdSAndroid Build Coastguard Worker 	for (i = 1; i < TOTAL_MAX_ARGS && i < max_args; i++) {
90*387f9dfdSAndroid Build Coastguard Worker 		ret = bpf_probe_read_user(&argp, sizeof(argp), &args[i]);
91*387f9dfdSAndroid Build Coastguard Worker 		if (ret < 0)
92*387f9dfdSAndroid Build Coastguard Worker 			return 0;
93*387f9dfdSAndroid Build Coastguard Worker 
94*387f9dfdSAndroid Build Coastguard Worker 		if (event->args_size > LAST_ARG)
95*387f9dfdSAndroid Build Coastguard Worker 			return 0;
96*387f9dfdSAndroid Build Coastguard Worker 
97*387f9dfdSAndroid Build Coastguard Worker 		ret = bpf_probe_read_user_str(&event->args[event->args_size], ARGSIZE, argp);
98*387f9dfdSAndroid Build Coastguard Worker 		if (ret < 0)
99*387f9dfdSAndroid Build Coastguard Worker 			return 0;
100*387f9dfdSAndroid Build Coastguard Worker 
101*387f9dfdSAndroid Build Coastguard Worker 		event->args_count++;
102*387f9dfdSAndroid Build Coastguard Worker 		event->args_size += ret;
103*387f9dfdSAndroid Build Coastguard Worker 	}
104*387f9dfdSAndroid Build Coastguard Worker 	/* try to read one more argument to check if there is one */
105*387f9dfdSAndroid Build Coastguard Worker 	ret = bpf_probe_read_user(&argp, sizeof(argp), &args[max_args]);
106*387f9dfdSAndroid Build Coastguard Worker 	if (ret < 0)
107*387f9dfdSAndroid Build Coastguard Worker 		return 0;
108*387f9dfdSAndroid Build Coastguard Worker 
109*387f9dfdSAndroid Build Coastguard Worker 	/* pointer to max_args+1 isn't null, asume we have more arguments */
110*387f9dfdSAndroid Build Coastguard Worker 	event->args_count++;
111*387f9dfdSAndroid Build Coastguard Worker 	return 0;
112*387f9dfdSAndroid Build Coastguard Worker }
113*387f9dfdSAndroid Build Coastguard Worker 
114*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/syscalls/sys_exit_execve")
tracepoint__syscalls__sys_exit_execve(struct trace_event_raw_sys_exit * ctx)115*387f9dfdSAndroid Build Coastguard Worker int tracepoint__syscalls__sys_exit_execve(struct trace_event_raw_sys_exit* ctx)
116*387f9dfdSAndroid Build Coastguard Worker {
117*387f9dfdSAndroid Build Coastguard Worker 	u64 id;
118*387f9dfdSAndroid Build Coastguard Worker 	pid_t pid;
119*387f9dfdSAndroid Build Coastguard Worker 	int ret;
120*387f9dfdSAndroid Build Coastguard Worker 	struct event *event;
121*387f9dfdSAndroid Build Coastguard Worker 
122*387f9dfdSAndroid Build Coastguard Worker 	if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0))
123*387f9dfdSAndroid Build Coastguard Worker 		return 0;
124*387f9dfdSAndroid Build Coastguard Worker 
125*387f9dfdSAndroid Build Coastguard Worker 	u32 uid = (u32)bpf_get_current_uid_gid();
126*387f9dfdSAndroid Build Coastguard Worker 
127*387f9dfdSAndroid Build Coastguard Worker 	if (valid_uid(targ_uid) && targ_uid != uid)
128*387f9dfdSAndroid Build Coastguard Worker 		return 0;
129*387f9dfdSAndroid Build Coastguard Worker 	id = bpf_get_current_pid_tgid();
130*387f9dfdSAndroid Build Coastguard Worker 	pid = (pid_t)id;
131*387f9dfdSAndroid Build Coastguard Worker 	event = bpf_map_lookup_elem(&execs, &pid);
132*387f9dfdSAndroid Build Coastguard Worker 	if (!event)
133*387f9dfdSAndroid Build Coastguard Worker 		return 0;
134*387f9dfdSAndroid Build Coastguard Worker 	ret = ctx->ret;
135*387f9dfdSAndroid Build Coastguard Worker 	if (ignore_failed && ret < 0)
136*387f9dfdSAndroid Build Coastguard Worker 		goto cleanup;
137*387f9dfdSAndroid Build Coastguard Worker 
138*387f9dfdSAndroid Build Coastguard Worker 	event->retval = ret;
139*387f9dfdSAndroid Build Coastguard Worker 	bpf_get_current_comm(&event->comm, sizeof(event->comm));
140*387f9dfdSAndroid Build Coastguard Worker 	size_t len = EVENT_SIZE(event);
141*387f9dfdSAndroid Build Coastguard Worker 	if (len <= sizeof(*event))
142*387f9dfdSAndroid Build Coastguard Worker 		bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event, len);
143*387f9dfdSAndroid Build Coastguard Worker cleanup:
144*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&execs, &pid);
145*387f9dfdSAndroid Build Coastguard Worker 	return 0;
146*387f9dfdSAndroid Build Coastguard Worker }
147*387f9dfdSAndroid Build Coastguard Worker 
148*387f9dfdSAndroid Build Coastguard Worker char LICENSE[] SEC("license") = "GPL";
149