lsm.c (3947B)
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 12struct { 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 19struct { 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 26struct { 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 33struct { 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 40struct { 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 47struct { 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 54struct 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 61struct 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 71struct 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 80char _license[] SEC("license") = "GPL"; 81 82int monitored_pid = 0; 83int mprotect_count = 0; 84int bprm_count = 0; 85 86SEC("lsm/file_mprotect") 87int 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 107SEC("lsm.s/bprm_committed_creds") 108int 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} 155SEC("lsm/task_free") /* lsm/ is ok, lsm.s/ fails */ 156int BPF_PROG(test_task_free, struct task_struct *task) 157{ 158 return 0; 159} 160 161int copy_test = 0; 162 163SEC("fentry.s/__x64_sys_setdomainname") 164int 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}