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")
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")
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 */
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")
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