1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Copyright 2020 Google LLC. 5 */ 6 7 #include "vmlinux.h" 8 #include <errno.h> 9 #include <bpf/bpf_helpers.h> 10 #include <bpf/bpf_tracing.h> 11 12 u32 monitored_pid = 0; 13 14 struct { 15 __uint(type, BPF_MAP_TYPE_RINGBUF); 16 __uint(max_entries, 1 << 12); 17 } ringbuf SEC(".maps"); 18 19 char _license[] SEC("license") = "GPL"; 20 21 bool use_ima_file_hash; 22 bool enable_bprm_creds_for_exec; 23 bool enable_kernel_read_file; 24 bool test_deny; 25 26 static void ima_test_common(struct file *file) 27 { 28 u64 ima_hash = 0; 29 u64 *sample; 30 int ret; 31 u32 pid; 32 33 pid = bpf_get_current_pid_tgid() >> 32; 34 if (pid == monitored_pid) { 35 if (!use_ima_file_hash) 36 ret = bpf_ima_inode_hash(file->f_inode, &ima_hash, 37 sizeof(ima_hash)); 38 else 39 ret = bpf_ima_file_hash(file, &ima_hash, 40 sizeof(ima_hash)); 41 if (ret < 0 || ima_hash == 0) 42 return; 43 44 sample = bpf_ringbuf_reserve(&ringbuf, sizeof(u64), 0); 45 if (!sample) 46 return; 47 48 *sample = ima_hash; 49 bpf_ringbuf_submit(sample, 0); 50 } 51 52 return; 53 } 54 55 static int ima_test_deny(void) 56 { 57 u32 pid; 58 59 pid = bpf_get_current_pid_tgid() >> 32; 60 if (pid == monitored_pid && test_deny) 61 return -EPERM; 62 63 return 0; 64 } 65 66 SEC("lsm.s/bprm_committed_creds") 67 void BPF_PROG(bprm_committed_creds, struct linux_binprm *bprm) 68 { 69 ima_test_common(bprm->file); 70 } 71 72 SEC("lsm.s/bprm_creds_for_exec") 73 int BPF_PROG(bprm_creds_for_exec, struct linux_binprm *bprm) 74 { 75 if (!enable_bprm_creds_for_exec) 76 return 0; 77 78 ima_test_common(bprm->file); 79 return 0; 80 } 81 82 SEC("lsm.s/kernel_read_file") 83 int BPF_PROG(kernel_read_file, struct file *file, enum kernel_read_file_id id, 84 bool contents) 85 { 86 int ret; 87 88 if (!enable_kernel_read_file) 89 return 0; 90 91 if (!contents) 92 return 0; 93 94 if (id != READING_POLICY) 95 return 0; 96 97 ret = ima_test_deny(); 98 if (ret < 0) 99 return ret; 100 101 ima_test_common(file); 102 return 0; 103 } 104