[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