1b94fa9f9SRoberto Sassu // SPDX-License-Identifier: GPL-2.0
2b94fa9f9SRoberto Sassu 
3b94fa9f9SRoberto Sassu /*
4b94fa9f9SRoberto Sassu  * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
5b94fa9f9SRoberto Sassu  *
6b94fa9f9SRoberto Sassu  * Author: Roberto Sassu <roberto.sassu@huawei.com>
7b94fa9f9SRoberto Sassu  */
8b94fa9f9SRoberto Sassu 
9b94fa9f9SRoberto Sassu #include "vmlinux.h"
10b94fa9f9SRoberto Sassu #include <errno.h>
11b94fa9f9SRoberto Sassu #include <bpf/bpf_helpers.h>
12b94fa9f9SRoberto Sassu #include <bpf/bpf_tracing.h>
138032cad1SJoanne Koong #include "bpf_misc.h"
14b94fa9f9SRoberto Sassu 
15b94fa9f9SRoberto Sassu extern struct bpf_key *bpf_lookup_system_key(__u64 id) __ksym;
16b94fa9f9SRoberto Sassu extern void bpf_key_put(struct bpf_key *key) __ksym;
17b94fa9f9SRoberto Sassu extern int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_ptr,
18b94fa9f9SRoberto Sassu 				      struct bpf_dynptr *sig_ptr,
19b94fa9f9SRoberto Sassu 				      struct bpf_key *trusted_keyring) __ksym;
20b94fa9f9SRoberto Sassu 
21b94fa9f9SRoberto Sassu struct {
22b94fa9f9SRoberto Sassu 	__uint(type, BPF_MAP_TYPE_RINGBUF);
238032cad1SJoanne Koong 	__uint(max_entries, 4096);
24b94fa9f9SRoberto Sassu } ringbuf SEC(".maps");
25b94fa9f9SRoberto Sassu 
26b94fa9f9SRoberto Sassu struct {
27b94fa9f9SRoberto Sassu 	__uint(type, BPF_MAP_TYPE_ARRAY);
28b94fa9f9SRoberto Sassu 	__uint(max_entries, 1);
29b94fa9f9SRoberto Sassu 	__type(key, __u32);
30b94fa9f9SRoberto Sassu 	__type(value, __u32);
31b94fa9f9SRoberto Sassu } array_map SEC(".maps");
32b94fa9f9SRoberto Sassu 
33b94fa9f9SRoberto Sassu int err, pid;
34b94fa9f9SRoberto Sassu 
35b94fa9f9SRoberto Sassu char _license[] SEC("license") = "GPL";
36b94fa9f9SRoberto Sassu 
37b94fa9f9SRoberto Sassu SEC("?lsm.s/bpf")
388032cad1SJoanne Koong __failure __msg("cannot pass in dynptr at an offset=-8")
BPF_PROG(not_valid_dynptr,int cmd,union bpf_attr * attr,unsigned int size)39b94fa9f9SRoberto Sassu int BPF_PROG(not_valid_dynptr, int cmd, union bpf_attr *attr, unsigned int size)
40b94fa9f9SRoberto Sassu {
41b94fa9f9SRoberto Sassu 	unsigned long val;
42b94fa9f9SRoberto Sassu 
43b94fa9f9SRoberto Sassu 	return bpf_verify_pkcs7_signature((struct bpf_dynptr *)&val,
44b94fa9f9SRoberto Sassu 					  (struct bpf_dynptr *)&val, NULL);
45b94fa9f9SRoberto Sassu }
46b94fa9f9SRoberto Sassu 
47b94fa9f9SRoberto Sassu SEC("?lsm.s/bpf")
488032cad1SJoanne Koong __failure __msg("arg#0 expected pointer to stack or dynptr_ptr")
BPF_PROG(not_ptr_to_stack,int cmd,union bpf_attr * attr,unsigned int size)49b94fa9f9SRoberto Sassu int BPF_PROG(not_ptr_to_stack, int cmd, union bpf_attr *attr, unsigned int size)
50b94fa9f9SRoberto Sassu {
51*ec97a76fSDave Marchevsky 	unsigned long val = 0;
52b94fa9f9SRoberto Sassu 
53b94fa9f9SRoberto Sassu 	return bpf_verify_pkcs7_signature((struct bpf_dynptr *)val,
54b94fa9f9SRoberto Sassu 					  (struct bpf_dynptr *)val, NULL);
55b94fa9f9SRoberto Sassu }
56b94fa9f9SRoberto Sassu 
57b94fa9f9SRoberto Sassu SEC("lsm.s/bpf")
BPF_PROG(dynptr_data_null,int cmd,union bpf_attr * attr,unsigned int size)58b94fa9f9SRoberto Sassu int BPF_PROG(dynptr_data_null, int cmd, union bpf_attr *attr, unsigned int size)
59b94fa9f9SRoberto Sassu {
60b94fa9f9SRoberto Sassu 	struct bpf_key *trusted_keyring;
61b94fa9f9SRoberto Sassu 	struct bpf_dynptr ptr;
62b94fa9f9SRoberto Sassu 	__u32 *value;
63b94fa9f9SRoberto Sassu 	int ret, zero = 0;
64b94fa9f9SRoberto Sassu 
65b94fa9f9SRoberto Sassu 	if (bpf_get_current_pid_tgid() >> 32 != pid)
66b94fa9f9SRoberto Sassu 		return 0;
67b94fa9f9SRoberto Sassu 
68b94fa9f9SRoberto Sassu 	value = bpf_map_lookup_elem(&array_map, &zero);
69b94fa9f9SRoberto Sassu 	if (!value)
70b94fa9f9SRoberto Sassu 		return 0;
71b94fa9f9SRoberto Sassu 
72b94fa9f9SRoberto Sassu 	/* Pass invalid flags. */
73b94fa9f9SRoberto Sassu 	ret = bpf_dynptr_from_mem(value, sizeof(*value), ((__u64)~0ULL), &ptr);
74b94fa9f9SRoberto Sassu 	if (ret != -EINVAL)
75b94fa9f9SRoberto Sassu 		return 0;
76b94fa9f9SRoberto Sassu 
77b94fa9f9SRoberto Sassu 	trusted_keyring = bpf_lookup_system_key(0);
78b94fa9f9SRoberto Sassu 	if (!trusted_keyring)
79b94fa9f9SRoberto Sassu 		return 0;
80b94fa9f9SRoberto Sassu 
81b94fa9f9SRoberto Sassu 	err = bpf_verify_pkcs7_signature(&ptr, &ptr, trusted_keyring);
82b94fa9f9SRoberto Sassu 
83b94fa9f9SRoberto Sassu 	bpf_key_put(trusted_keyring);
84b94fa9f9SRoberto Sassu 
85b94fa9f9SRoberto Sassu 	return 0;
86b94fa9f9SRoberto Sassu }
87