|
39 | 39 | #include <linux/tracepoint.h>
|
40 | 40 | #include <linux/overflow.h>
|
41 | 41 | #include <linux/cookie.h>
|
| 42 | +#include <linux/verification.h> |
42 | 43 |
|
43 | 44 | #include <net/netfilter/nf_bpf_link.h>
|
44 | 45 | #include <net/netkit.h>
|
@@ -2785,8 +2786,44 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
|
2785 | 2786 | }
|
2786 | 2787 | }
|
2787 | 2788 |
|
| 2789 | +static int bpf_prog_verify_signature(struct bpf_prog *prog, union bpf_attr *attr, |
| 2790 | + bool is_kernel) |
| 2791 | +{ |
| 2792 | + bpfptr_t usig = make_bpfptr(attr->signature, is_kernel); |
| 2793 | + struct bpf_dynptr_kern sig_ptr, insns_ptr; |
| 2794 | + struct bpf_key *key = NULL; |
| 2795 | + void *sig; |
| 2796 | + int err = 0; |
| 2797 | + |
| 2798 | + if (system_keyring_id_check(attr->keyring_id) == 0) |
| 2799 | + key = bpf_lookup_system_key(attr->keyring_id); |
| 2800 | + else |
| 2801 | + key = bpf_lookup_user_key(attr->keyring_id, 0); |
| 2802 | + |
| 2803 | + if (!key) |
| 2804 | + return -EINVAL; |
| 2805 | + |
| 2806 | + sig = kvmemdup_bpfptr(usig, attr->signature_size); |
| 2807 | + if (IS_ERR(sig)) { |
| 2808 | + bpf_key_put(key); |
| 2809 | + return -ENOMEM; |
| 2810 | + } |
| 2811 | + |
| 2812 | + bpf_dynptr_init(&sig_ptr, sig, BPF_DYNPTR_TYPE_LOCAL, 0, |
| 2813 | + attr->signature_size); |
| 2814 | + bpf_dynptr_init(&insns_ptr, prog->insnsi, BPF_DYNPTR_TYPE_LOCAL, 0, |
| 2815 | + prog->len * sizeof(struct bpf_insn)); |
| 2816 | + |
| 2817 | + err = bpf_verify_pkcs7_signature((struct bpf_dynptr *)&insns_ptr, |
| 2818 | + (struct bpf_dynptr *)&sig_ptr, key); |
| 2819 | + |
| 2820 | + bpf_key_put(key); |
| 2821 | + kvfree(sig); |
| 2822 | + return err; |
| 2823 | +} |
| 2824 | + |
2788 | 2825 | /* last field in 'union bpf_attr' used by this command */
|
2789 |
| -#define BPF_PROG_LOAD_LAST_FIELD fd_array_cnt |
| 2826 | +#define BPF_PROG_LOAD_LAST_FIELD keyring_id |
2790 | 2827 |
|
2791 | 2828 | static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
|
2792 | 2829 | {
|
@@ -2950,6 +2987,12 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
|
2950 | 2987 | /* eBPF programs must be GPL compatible to use GPL-ed functions */
|
2951 | 2988 | prog->gpl_compatible = license_is_gpl_compatible(license) ? 1 : 0;
|
2952 | 2989 |
|
| 2990 | + if (attr->signature) { |
| 2991 | + err = bpf_prog_verify_signature(prog, attr, uattr.is_kernel); |
| 2992 | + if (err) |
| 2993 | + goto free_prog; |
| 2994 | + } |
| 2995 | + |
2953 | 2996 | prog->orig_prog = NULL;
|
2954 | 2997 | prog->jited = 0;
|
2955 | 2998 |
|
|
0 commit comments