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