[PATCH bpf-next v7 1/5] bpf: Implement signature verification for BPF programs
Chris Mason
clm at meta.com
Tue Oct 7 16:42:10 UTC 2025
Hi KP,
On Sun, 21 Sep 2025 18:01:16 +0200 KP Singh <kpsingh at kernel.org> wrote:
> This patch extends the BPF_PROG_LOAD command by adding three new fields
> to `union bpf_attr` in the user-space API:
>
> - signature: A pointer to the signature blob.
> - signature_size: The size of the signature blob.
> - keyring_id: The serial number of a loaded kernel keyring (e.g.,
> the user or session keyring) containing the trusted public keys.
>
> When a BPF program is loaded with a signature, the kernel:
>
> 1. Retrieves the trusted keyring using the provided `keyring_id`.
> 2. Verifies the supplied signature against the BPF program's
> instruction buffer.
> 3. If the signature is valid and was generated by a key in the trusted
> keyring, the program load proceeds.
> 4. If no signature is provided, the load proceeds as before, allowing
> for backward compatibility. LSMs can chose to restrict unsigned
> programs and implement a security policy.
> 5. If signature verification fails for any reason,
> the program is not loaded.
>
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index cf7173b1bb83..8a3c3d26f6e2 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -39,6 +39,7 @@
> #include <linux/tracepoint.h>
> #include <linux/overflow.h>
> #include <linux/cookie.h>
> +#include <linux/verification.h>
>
> #include <net/netfilter/nf_bpf_link.h>
> #include <net/netkit.h>
> @@ -2785,8 +2786,44 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
> }
> }
>
> +static int bpf_prog_verify_signature(struct bpf_prog *prog, union bpf_attr *attr,
> + bool is_kernel)
> +{
> + bpfptr_t usig = make_bpfptr(attr->signature, is_kernel);
> + struct bpf_dynptr_kern sig_ptr, insns_ptr;
> + struct bpf_key *key = NULL;
> + void *sig;
> + int err = 0;
> +
> + if (system_keyring_id_check(attr->keyring_id) == 0)
> + key = bpf_lookup_system_key(attr->keyring_id);
> + else
> + key = bpf_lookup_user_key(attr->keyring_id, 0);
> +
> + if (!key)
> + return -EINVAL;
> +
> + sig = kvmemdup_bpfptr(usig, attr->signature_size);
Should there be some validation on signature_size? It looks like we're
giving vmalloc exactly what userland sent.
-chris
More information about the Linux-security-module-archive
mailing list