1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4 * Copyright 2020 Google LLC.
5 */
6
7 #include "vmlinux.h"
8 #include <bpf/bpf_helpers.h>
9 #include <bpf/bpf_tracing.h>
10 #include <errno.h>
11
12 struct {
13 __uint(type, BPF_MAP_TYPE_ARRAY);
14 __uint(max_entries, 1);
15 __type(key, __u32);
16 __type(value, __u64);
17 } array SEC(".maps");
18
19 struct {
20 __uint(type, BPF_MAP_TYPE_HASH);
21 __uint(max_entries, 1);
22 __type(key, __u32);
23 __type(value, __u64);
24 } hash SEC(".maps");
25
26 struct {
27 __uint(type, BPF_MAP_TYPE_LRU_HASH);
28 __uint(max_entries, 1);
29 __type(key, __u32);
30 __type(value, __u64);
31 } lru_hash SEC(".maps");
32
33 struct {
34 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
35 __uint(max_entries, 1);
36 __type(key, __u32);
37 __type(value, __u64);
38 } percpu_array SEC(".maps");
39
40 struct {
41 __uint(type, BPF_MAP_TYPE_PERCPU_HASH);
42 __uint(max_entries, 1);
43 __type(key, __u32);
44 __type(value, __u64);
45 } percpu_hash SEC(".maps");
46
47 struct {
48 __uint(type, BPF_MAP_TYPE_LRU_PERCPU_HASH);
49 __uint(max_entries, 1);
50 __type(key, __u32);
51 __type(value, __u64);
52 } lru_percpu_hash SEC(".maps");
53
54 struct inner_map {
55 __uint(type, BPF_MAP_TYPE_ARRAY);
56 __uint(max_entries, 1);
57 __type(key, int);
58 __type(value, __u64);
59 } inner_map SEC(".maps");
60
61 struct outer_arr {
62 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
63 __uint(max_entries, 1);
64 __uint(key_size, sizeof(int));
65 __uint(value_size, sizeof(int));
66 __array(values, struct inner_map);
67 } outer_arr SEC(".maps") = {
68 .values = { [0] = &inner_map },
69 };
70
71 struct outer_hash {
72 __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
73 __uint(max_entries, 1);
74 __uint(key_size, sizeof(int));
75 __array(values, struct inner_map);
76 } outer_hash SEC(".maps") = {
77 .values = { [0] = &inner_map },
78 };
79
80 char _license[] SEC("license") = "GPL";
81
82 int monitored_pid = 0;
83 int mprotect_count = 0;
84 int bprm_count = 0;
85
86 SEC("lsm/file_mprotect")
BPF_PROG(test_int_hook,struct vm_area_struct * vma,unsigned long reqprot,unsigned long prot,int ret)87 int BPF_PROG(test_int_hook, struct vm_area_struct *vma,
88 unsigned long reqprot, unsigned long prot, int ret)
89 {
90 if (ret != 0)
91 return ret;
92
93 __u32 pid = bpf_get_current_pid_tgid() >> 32;
94 int is_stack = 0;
95
96 is_stack = (vma->vm_start <= vma->vm_mm->start_stack &&
97 vma->vm_end >= vma->vm_mm->start_stack);
98
99 if (is_stack && monitored_pid == pid) {
100 mprotect_count++;
101 ret = -EPERM;
102 }
103
104 return ret;
105 }
106
107 SEC("lsm.s/bprm_committed_creds")
BPF_PROG(test_void_hook,struct linux_binprm * bprm)108 int BPF_PROG(test_void_hook, struct linux_binprm *bprm)
109 {
110 __u32 pid = bpf_get_current_pid_tgid() >> 32;
111 struct inner_map *inner_map;
112 char args[64];
113 __u32 key = 0;
114 __u64 *value;
115
116 if (monitored_pid == pid)
117 bprm_count++;
118
119 bpf_copy_from_user(args, sizeof(args), (void *)bprm->vma->vm_mm->arg_start);
120 bpf_copy_from_user(args, sizeof(args), (void *)bprm->mm->arg_start);
121
122 value = bpf_map_lookup_elem(&array, &key);
123 if (value)
124 *value = 0;
125 value = bpf_map_lookup_elem(&hash, &key);
126 if (value)
127 *value = 0;
128 value = bpf_map_lookup_elem(&lru_hash, &key);
129 if (value)
130 *value = 0;
131 value = bpf_map_lookup_elem(&percpu_array, &key);
132 if (value)
133 *value = 0;
134 value = bpf_map_lookup_elem(&percpu_hash, &key);
135 if (value)
136 *value = 0;
137 value = bpf_map_lookup_elem(&lru_percpu_hash, &key);
138 if (value)
139 *value = 0;
140 inner_map = bpf_map_lookup_elem(&outer_arr, &key);
141 if (inner_map) {
142 value = bpf_map_lookup_elem(inner_map, &key);
143 if (value)
144 *value = 0;
145 }
146 inner_map = bpf_map_lookup_elem(&outer_hash, &key);
147 if (inner_map) {
148 value = bpf_map_lookup_elem(inner_map, &key);
149 if (value)
150 *value = 0;
151 }
152
153 return 0;
154 }
155 SEC("lsm/task_free") /* lsm/ is ok, lsm.s/ fails */
BPF_PROG(test_task_free,struct task_struct * task)156 int BPF_PROG(test_task_free, struct task_struct *task)
157 {
158 return 0;
159 }
160
161 int copy_test = 0;
162
163 SEC("fentry.s/__x64_sys_setdomainname")
BPF_PROG(test_sys_setdomainname,struct pt_regs * regs)164 int BPF_PROG(test_sys_setdomainname, struct pt_regs *regs)
165 {
166 void *ptr = (void *)PT_REGS_PARM1(regs);
167 int len = PT_REGS_PARM2(regs);
168 int buf = 0;
169 long ret;
170
171 ret = bpf_copy_from_user(&buf, sizeof(buf), ptr);
172 if (len == -2 && ret == 0 && buf == 1234)
173 copy_test++;
174 if (len == -3 && ret == -EFAULT)
175 copy_test++;
176 if (len == -4 && ret == -EFAULT)
177 copy_test++;
178 return 0;
179 }
180