162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci/* 462306a36Sopenharmony_ci * Copyright 2020 Google LLC. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include "vmlinux.h" 862306a36Sopenharmony_ci#include <errno.h> 962306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 1062306a36Sopenharmony_ci#include <bpf/bpf_tracing.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ciu32 monitored_pid = 0; 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct { 1562306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_RINGBUF); 1662306a36Sopenharmony_ci __uint(max_entries, 1 << 12); 1762306a36Sopenharmony_ci} ringbuf SEC(".maps"); 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cibool use_ima_file_hash; 2262306a36Sopenharmony_cibool enable_bprm_creds_for_exec; 2362306a36Sopenharmony_cibool enable_kernel_read_file; 2462306a36Sopenharmony_cibool test_deny; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistatic void ima_test_common(struct file *file) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci u64 ima_hash = 0; 2962306a36Sopenharmony_ci u64 *sample; 3062306a36Sopenharmony_ci int ret; 3162306a36Sopenharmony_ci u32 pid; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci pid = bpf_get_current_pid_tgid() >> 32; 3462306a36Sopenharmony_ci if (pid == monitored_pid) { 3562306a36Sopenharmony_ci if (!use_ima_file_hash) 3662306a36Sopenharmony_ci ret = bpf_ima_inode_hash(file->f_inode, &ima_hash, 3762306a36Sopenharmony_ci sizeof(ima_hash)); 3862306a36Sopenharmony_ci else 3962306a36Sopenharmony_ci ret = bpf_ima_file_hash(file, &ima_hash, 4062306a36Sopenharmony_ci sizeof(ima_hash)); 4162306a36Sopenharmony_ci if (ret < 0 || ima_hash == 0) 4262306a36Sopenharmony_ci return; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci sample = bpf_ringbuf_reserve(&ringbuf, sizeof(u64), 0); 4562306a36Sopenharmony_ci if (!sample) 4662306a36Sopenharmony_ci return; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci *sample = ima_hash; 4962306a36Sopenharmony_ci bpf_ringbuf_submit(sample, 0); 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci return; 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic int ima_test_deny(void) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci u32 pid; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci pid = bpf_get_current_pid_tgid() >> 32; 6062306a36Sopenharmony_ci if (pid == monitored_pid && test_deny) 6162306a36Sopenharmony_ci return -EPERM; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci return 0; 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ciSEC("lsm.s/bprm_committed_creds") 6762306a36Sopenharmony_civoid BPF_PROG(bprm_committed_creds, struct linux_binprm *bprm) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci ima_test_common(bprm->file); 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciSEC("lsm.s/bprm_creds_for_exec") 7362306a36Sopenharmony_ciint BPF_PROG(bprm_creds_for_exec, struct linux_binprm *bprm) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci if (!enable_bprm_creds_for_exec) 7662306a36Sopenharmony_ci return 0; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci ima_test_common(bprm->file); 7962306a36Sopenharmony_ci return 0; 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ciSEC("lsm.s/kernel_read_file") 8362306a36Sopenharmony_ciint BPF_PROG(kernel_read_file, struct file *file, enum kernel_read_file_id id, 8462306a36Sopenharmony_ci bool contents) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci int ret; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci if (!enable_kernel_read_file) 8962306a36Sopenharmony_ci return 0; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci if (!contents) 9262306a36Sopenharmony_ci return 0; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci if (id != READING_POLICY) 9562306a36Sopenharmony_ci return 0; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci ret = ima_test_deny(); 9862306a36Sopenharmony_ci if (ret < 0) 9962306a36Sopenharmony_ci return ret; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci ima_test_common(file); 10262306a36Sopenharmony_ci return 0; 10362306a36Sopenharmony_ci} 104