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