bpf: Move unprivileged checks into map_create() and bpf_prog_load()
Make each bpf() syscall command a bit more self-contained, making it easier to further enhance it. We move sysctl_unprivileged_bpf_disabled handling down to map_create() and bpf_prog_load(), two special commands in this regard. Also swap the order of checks, calling bpf_capable() only if sysctl_unprivileged_bpf_disabled is true, avoiding unnecessary audit messages. Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/bpf/20230613223533.3689589-2-andrii@kernel.org
This commit is contained in:
committed by
Daniel Borkmann
parent
ab5d47bd41
commit
1d28635abc
@ -1157,6 +1157,15 @@ static int map_create(union bpf_attr *attr)
|
|||||||
!node_online(numa_node)))
|
!node_online(numa_node)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Intent here is for unprivileged_bpf_disabled to block BPF map
|
||||||
|
* creation for unprivileged users; other actions depend
|
||||||
|
* on fd availability and access to bpffs, so are dependent on
|
||||||
|
* object creation success. Even with unprivileged BPF disabled,
|
||||||
|
* capability checks are still carried out.
|
||||||
|
*/
|
||||||
|
if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
/* find map type and init map: hashtable vs rbtree vs bloom vs ... */
|
/* find map type and init map: hashtable vs rbtree vs bloom vs ... */
|
||||||
map = find_and_alloc_map(attr);
|
map = find_and_alloc_map(attr);
|
||||||
if (IS_ERR(map))
|
if (IS_ERR(map))
|
||||||
@ -2532,6 +2541,16 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
|
|||||||
/* eBPF programs must be GPL compatible to use GPL-ed functions */
|
/* eBPF programs must be GPL compatible to use GPL-ed functions */
|
||||||
is_gpl = license_is_gpl_compatible(license);
|
is_gpl = license_is_gpl_compatible(license);
|
||||||
|
|
||||||
|
/* Intent here is for unprivileged_bpf_disabled to block BPF program
|
||||||
|
* creation for unprivileged users; other actions depend
|
||||||
|
* on fd availability and access to bpffs, so are dependent on
|
||||||
|
* object creation success. Even with unprivileged BPF disabled,
|
||||||
|
* capability checks are still carried out for these
|
||||||
|
* and other operations.
|
||||||
|
*/
|
||||||
|
if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
if (attr->insn_cnt == 0 ||
|
if (attr->insn_cnt == 0 ||
|
||||||
attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
|
attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
|
||||||
return -E2BIG;
|
return -E2BIG;
|
||||||
@ -5030,23 +5049,8 @@ out_prog_put:
|
|||||||
static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
|
static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
|
||||||
{
|
{
|
||||||
union bpf_attr attr;
|
union bpf_attr attr;
|
||||||
bool capable;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
capable = bpf_capable() || !sysctl_unprivileged_bpf_disabled;
|
|
||||||
|
|
||||||
/* Intent here is for unprivileged_bpf_disabled to block key object
|
|
||||||
* creation commands for unprivileged users; other actions depend
|
|
||||||
* of fd availability and access to bpffs, so are dependent on
|
|
||||||
* object creation success. Capabilities are later verified for
|
|
||||||
* operations such as load and map create, so even with unprivileged
|
|
||||||
* BPF disabled, capability checks are still carried out for these
|
|
||||||
* and other operations.
|
|
||||||
*/
|
|
||||||
if (!capable &&
|
|
||||||
(cmd == BPF_MAP_CREATE || cmd == BPF_PROG_LOAD))
|
|
||||||
return -EPERM;
|
|
||||||
|
|
||||||
err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size);
|
err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
Reference in New Issue
Block a user