0001
0002
0003
0004
0005
0006
0007 #include "vmlinux.h"
0008 #include <errno.h>
0009 #include <bpf/bpf_helpers.h>
0010 #include <bpf/bpf_tracing.h>
0011
0012 u32 monitored_pid = 0;
0013
0014 struct {
0015 __uint(type, BPF_MAP_TYPE_RINGBUF);
0016 __uint(max_entries, 1 << 12);
0017 } ringbuf SEC(".maps");
0018
0019 char _license[] SEC("license") = "GPL";
0020
0021 bool use_ima_file_hash;
0022 bool enable_bprm_creds_for_exec;
0023 bool enable_kernel_read_file;
0024 bool test_deny;
0025
0026 static void ima_test_common(struct file *file)
0027 {
0028 u64 ima_hash = 0;
0029 u64 *sample;
0030 int ret;
0031 u32 pid;
0032
0033 pid = bpf_get_current_pid_tgid() >> 32;
0034 if (pid == monitored_pid) {
0035 if (!use_ima_file_hash)
0036 ret = bpf_ima_inode_hash(file->f_inode, &ima_hash,
0037 sizeof(ima_hash));
0038 else
0039 ret = bpf_ima_file_hash(file, &ima_hash,
0040 sizeof(ima_hash));
0041 if (ret < 0 || ima_hash == 0)
0042 return;
0043
0044 sample = bpf_ringbuf_reserve(&ringbuf, sizeof(u64), 0);
0045 if (!sample)
0046 return;
0047
0048 *sample = ima_hash;
0049 bpf_ringbuf_submit(sample, 0);
0050 }
0051
0052 return;
0053 }
0054
0055 static int ima_test_deny(void)
0056 {
0057 u32 pid;
0058
0059 pid = bpf_get_current_pid_tgid() >> 32;
0060 if (pid == monitored_pid && test_deny)
0061 return -EPERM;
0062
0063 return 0;
0064 }
0065
0066 SEC("lsm.s/bprm_committed_creds")
0067 void BPF_PROG(bprm_committed_creds, struct linux_binprm *bprm)
0068 {
0069 ima_test_common(bprm->file);
0070 }
0071
0072 SEC("lsm.s/bprm_creds_for_exec")
0073 int BPF_PROG(bprm_creds_for_exec, struct linux_binprm *bprm)
0074 {
0075 if (!enable_bprm_creds_for_exec)
0076 return 0;
0077
0078 ima_test_common(bprm->file);
0079 return 0;
0080 }
0081
0082 SEC("lsm.s/kernel_read_file")
0083 int BPF_PROG(kernel_read_file, struct file *file, enum kernel_read_file_id id,
0084 bool contents)
0085 {
0086 int ret;
0087
0088 if (!enable_kernel_read_file)
0089 return 0;
0090
0091 if (!contents)
0092 return 0;
0093
0094 if (id != READING_POLICY)
0095 return 0;
0096
0097 ret = ima_test_deny();
0098 if (ret < 0)
0099 return ret;
0100
0101 ima_test_common(file);
0102 return 0;
0103 }