155714Skris// SPDX-License-Identifier: GPL-2.0 255714Skris 355714Skris/* 455714Skris * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH 555714Skris * 655714Skris * Author: Roberto Sassu <roberto.sassu@huawei.com> 755714Skris */ 855714Skris 955714Skris#include "vmlinux.h" 1055714Skris#include <errno.h> 1155714Skris#include <bpf/bpf_helpers.h> 1255714Skris#include <bpf/bpf_tracing.h> 1355714Skris#include "bpf_kfuncs.h" 1455714Skris 1555714Skris#define MAX_DATA_SIZE (1024 * 1024) 1655714Skris#define MAX_SIG_SIZE 1024 1755714Skris 1855714Skris__u32 monitored_pid; 1955714Skris__u32 user_keyring_serial; 2055714Skris__u64 system_keyring_id; 2155714Skris 2255714Skrisstruct data { 2355714Skris __u8 data[MAX_DATA_SIZE]; 2455714Skris __u32 data_len; 2555714Skris __u8 sig[MAX_SIG_SIZE]; 2655714Skris __u32 sig_len; 2755714Skris}; 2855714Skris 2955714Skrisstruct { 3055714Skris __uint(type, BPF_MAP_TYPE_ARRAY); 3155714Skris __uint(max_entries, 1); 3255714Skris __type(key, __u32); 3355714Skris __type(value, struct data); 3455714Skris} data_input SEC(".maps"); 3555714Skris 3655714Skrischar _license[] SEC("license") = "GPL"; 3755714Skris 3855714SkrisSEC("lsm.s/bpf") 3955714Skrisint BPF_PROG(bpf, int cmd, union bpf_attr *attr, unsigned int size) 4055714Skris{ 4155714Skris struct bpf_dynptr data_ptr, sig_ptr; 4255714Skris struct data *data_val; 4355714Skris struct bpf_key *trusted_keyring; 4455714Skris __u32 pid; 4555714Skris __u64 value; 4655714Skris int ret, zero = 0; 4755714Skris 4855714Skris pid = bpf_get_current_pid_tgid() >> 32; 4955714Skris if (pid != monitored_pid) 5055714Skris return 0; 51 52 data_val = bpf_map_lookup_elem(&data_input, &zero); 53 if (!data_val) 54 return 0; 55 56 ret = bpf_probe_read_kernel(&value, sizeof(value), &attr->value); 57 if (ret) 58 return ret; 59 60 ret = bpf_copy_from_user(data_val, sizeof(struct data), 61 (void *)(unsigned long)value); 62 if (ret) 63 return ret; 64 65 if (data_val->data_len > sizeof(data_val->data)) 66 return -EINVAL; 67 68 bpf_dynptr_from_mem(data_val->data, data_val->data_len, 0, &data_ptr); 69 70 if (data_val->sig_len > sizeof(data_val->sig)) 71 return -EINVAL; 72 73 bpf_dynptr_from_mem(data_val->sig, data_val->sig_len, 0, &sig_ptr); 74 75 if (user_keyring_serial) 76 trusted_keyring = bpf_lookup_user_key(user_keyring_serial, 0); 77 else 78 trusted_keyring = bpf_lookup_system_key(system_keyring_id); 79 80 if (!trusted_keyring) 81 return -ENOENT; 82 83 ret = bpf_verify_pkcs7_signature(&data_ptr, &sig_ptr, trusted_keyring); 84 85 bpf_key_put(trusted_keyring); 86 87 return ret; 88} 89