Re: [PATCH bpf-next 4/5] selinux: Add BPF_LOADER_LOAD_FD syscall permission

[email protected]
Newsgroups org.kernel.vger.selinux,org.kernel.vger.bpf
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] The SELinux access control check for BPF_LOADER_LOAD_FD is completely bypassed if the bpf_token_perms policy capability is enabled, leading to Privilege Escalation.

Pre-existing issues:
- [High] BPF_LOADER_LOAD_FD fails unconditionally with -EINVAL if CONFIG_BPF_JIT is disabled.
--

--- Patch [4]: [PATCH bpf-next 4/5] selinux: Add BPF_LOADER_LOAD_FD syscall permission ---
commit aa42284da62cb224bfd501dfd4306e6584b6a8e1
Author: Thiébaud Weksteen <[email protected]>

selinux: Add BPF_LOADER_LOAD_FD syscall permission

Add the BPF_LOADER_LOAD_FD permission to gate the bpf syscall command of
the same name.

> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index e7c5993f69545..b4ff5ea5306df 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -7196,6 +7196,10 @@ static int selinux_bpf(int cmd, union bpf_attr *attr,
>  		ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
>  				   NULL);
>  		break;
> +	case BPF_LOADER_LOAD_FD:
> +		ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__LOADER_LOAD_FD,
> +				   NULL);
> +		break;

[Severity: High]
Is it possible this check can be completely bypassed if the bpf_token_perms
policy capability is enabled?

Looking at selinux_bpf() earlier in this file, there is an early return:

	if (selinux_policycap_bpf_token_perms())
		return 0;

Because BPF_LOADER_LOAD_FD doesn't have a fine-grained SELinux hook later on,
this early return skips the access control check.

Furthermore, loader_load_fd() internally calls kern_sys_bpf() which executes
the inner map creations and program loads with is_kernel = true:

	return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size, KERNEL_BPFPTR(NULL), 0);

This passes the kernel SID (SECINITSID_KERNEL) to the fine-grained hooks
instead of the user's SID:

	ssid = kernel ? SECINITSID_KERNEL : bpfsec->sid;

Will this allow a user with CAP_BPF to bypass their SELinux constraints and
load arbitrary programs as the kernel?

[Severity: High]
This isn't a bug introduced by this patch, but will BPF_LOADER_LOAD_FD fail
unconditionally if CONFIG_BPF_JIT is disabled?

Looking at loader_load_fd() in kernel/bpf/syscall.c, it unconditionally calls:

	err = kern_sys_bpf(BPF_PROG_TEST_RUN, &sattr, sizeof(sattr));

However, in kern_sys_bpf(), the BPF_PROG_TEST_RUN case is compiled out when
CONFIG_BPF_JIT is disabled:

	#ifdef CONFIG_BPF_JIT
	case BPF_PROG_TEST_RUN:

This causes it to fall through to the default handler which returns -EINVAL for
BPF_PROG_TEST_RUN, breaking the feature entirely on non-JIT configurations.

>  	default:
>  		ret = 0;
>  		break;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.