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