1*f108662bSSong Liu // SPDX-License-Identifier: GPL-2.0
2*f108662bSSong Liu /* Copyright (c) 2021 Facebook */
3*f108662bSSong Liu #include "vmlinux.h"
4*f108662bSSong Liu #include <bpf/bpf_helpers.h>
5*f108662bSSong Liu #include <bpf/bpf_tracing.h>
6*f108662bSSong Liu 
7*f108662bSSong Liu char _license[] SEC("license") = "GPL";
8*f108662bSSong Liu 
9*f108662bSSong Liu struct callback_ctx {
10*f108662bSSong Liu 	int dummy;
11*f108662bSSong Liu };
12*f108662bSSong Liu 
13*f108662bSSong Liu #define VM_EXEC		0x00000004
14*f108662bSSong Liu #define DNAME_INLINE_LEN 32
15*f108662bSSong Liu 
16*f108662bSSong Liu pid_t target_pid = 0;
17*f108662bSSong Liu char d_iname[DNAME_INLINE_LEN] = {0};
18*f108662bSSong Liu __u32 found_vm_exec = 0;
19*f108662bSSong Liu __u64 addr = 0;
20*f108662bSSong Liu int find_zero_ret = -1;
21*f108662bSSong Liu int find_addr_ret = -1;
22*f108662bSSong Liu 
check_vma(struct task_struct * task,struct vm_area_struct * vma,struct callback_ctx * data)23*f108662bSSong Liu static long check_vma(struct task_struct *task, struct vm_area_struct *vma,
24*f108662bSSong Liu 		      struct callback_ctx *data)
25*f108662bSSong Liu {
26*f108662bSSong Liu 	if (vma->vm_file)
27*f108662bSSong Liu 		bpf_probe_read_kernel_str(d_iname, DNAME_INLINE_LEN - 1,
28*f108662bSSong Liu 					  vma->vm_file->f_path.dentry->d_iname);
29*f108662bSSong Liu 
30*f108662bSSong Liu 	/* check for VM_EXEC */
31*f108662bSSong Liu 	if (vma->vm_flags & VM_EXEC)
32*f108662bSSong Liu 		found_vm_exec = 1;
33*f108662bSSong Liu 
34*f108662bSSong Liu 	return 0;
35*f108662bSSong Liu }
36*f108662bSSong Liu 
37*f108662bSSong Liu SEC("raw_tp/sys_enter")
handle_getpid(void)38*f108662bSSong Liu int handle_getpid(void)
39*f108662bSSong Liu {
40*f108662bSSong Liu 	struct task_struct *task = bpf_get_current_task_btf();
41*f108662bSSong Liu 	struct callback_ctx data = {};
42*f108662bSSong Liu 
43*f108662bSSong Liu 	if (task->pid != target_pid)
44*f108662bSSong Liu 		return 0;
45*f108662bSSong Liu 
46*f108662bSSong Liu 	find_addr_ret = bpf_find_vma(task, addr, check_vma, &data, 0);
47*f108662bSSong Liu 
48*f108662bSSong Liu 	/* this should return -ENOENT */
49*f108662bSSong Liu 	find_zero_ret = bpf_find_vma(task, 0, check_vma, &data, 0);
50*f108662bSSong Liu 	return 0;
51*f108662bSSong Liu }
52*f108662bSSong Liu 
53*f108662bSSong Liu SEC("perf_event")
handle_pe(void)54*f108662bSSong Liu int handle_pe(void)
55*f108662bSSong Liu {
56*f108662bSSong Liu 	struct task_struct *task = bpf_get_current_task_btf();
57*f108662bSSong Liu 	struct callback_ctx data = {};
58*f108662bSSong Liu 
59*f108662bSSong Liu 	if (task->pid != target_pid)
60*f108662bSSong Liu 		return 0;
61*f108662bSSong Liu 
62*f108662bSSong Liu 	find_addr_ret = bpf_find_vma(task, addr, check_vma, &data, 0);
63*f108662bSSong Liu 
64*f108662bSSong Liu 	/* In NMI, this should return -EBUSY, as the previous call is using
65*f108662bSSong Liu 	 * the irq_work.
66*f108662bSSong Liu 	 */
67*f108662bSSong Liu 	find_zero_ret = bpf_find_vma(task, 0, check_vma, &data, 0);
68*f108662bSSong Liu 	return 0;
69*f108662bSSong Liu }
70