Skip to content

Commit a17b53c

Browse files
Alexei Starovoitovborkmann
authored andcommitted
bpf, capability: Introduce CAP_BPF
Split BPF operations that are allowed under CAP_SYS_ADMIN into combination of CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN. For backward compatibility include them in CAP_SYS_ADMIN as well. The end result provides simple safety model for applications that use BPF: - to load tracing program types BPF_PROG_TYPE_{KPROBE, TRACEPOINT, PERF_EVENT, RAW_TRACEPOINT, etc} use CAP_BPF and CAP_PERFMON - to load networking program types BPF_PROG_TYPE_{SCHED_CLS, XDP, SK_SKB, etc} use CAP_BPF and CAP_NET_ADMIN There are few exceptions from this rule: - bpf_trace_printk() is allowed in networking programs, but it's using tracing mechanism, hence this helper needs additional CAP_PERFMON if networking program is using this helper. - BPF_F_ZERO_SEED flag for hash/lru map is allowed under CAP_SYS_ADMIN only to discourage production use. - BPF HW offload is allowed under CAP_SYS_ADMIN. - bpf_probe_write_user() is allowed under CAP_SYS_ADMIN only. CAPs are not checked at attach/detach time with two exceptions: - loading BPF_PROG_TYPE_CGROUP_SKB is allowed for unprivileged users, hence CAP_NET_ADMIN is required at attach time. - flow_dissector detach doesn't check prog FD at detach, hence CAP_NET_ADMIN is required at detach time. CAP_SYS_ADMIN is required to iterate BPF objects (progs, maps, links) via get_next_id command and convert them to file descriptor via GET_FD_BY_ID command. This restriction guarantees that mutliple tasks with CAP_BPF are not able to affect each other. That leads to clean isolation of tasks. For example: task A with CAP_BPF and CAP_NET_ADMIN loads and attaches a firewall via bpf_link. task B with the same capabilities cannot detach that firewall unless task A explicitly passed link FD to task B via scm_rights or bpffs. CAP_SYS_ADMIN can still detach/unload everything. Two networking user apps with CAP_SYS_ADMIN and CAP_NET_ADMIN can accidentely mess with each other programs and maps. Two networking user apps with CAP_NET_ADMIN and CAP_BPF cannot affect each other. CAP_NET_ADMIN + CAP_BPF allows networking programs access only packet data. Such networking progs cannot access arbitrary kernel memory or leak pointers. bpftool, bpftrace, bcc tools binaries should NOT be installed with CAP_BPF and CAP_PERFMON, since unpriv users will be able to read kernel secrets. But users with these two permissions will be able to use these tracing tools. CAP_PERFMON is least secure, since it allows kprobes and kernel memory access. CAP_NET_ADMIN can stop network traffic via iproute2. CAP_BPF is the safest from security point of view and harmless on its own. Having CAP_BPF and/or CAP_NET_ADMIN is not enough to write into arbitrary map and if that map is used by firewall-like bpf prog. CAP_BPF allows many bpf prog_load commands in parallel. The verifier may consume large amount of memory and significantly slow down the system. Existing unprivileged BPF operations are not affected. In particular unprivileged users are allowed to load socket_filter and cg_skb program types and to create array, hash, prog_array, map-in-map map types. Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 0ee52c0 commit a17b53c

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

include/linux/capability.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ static inline bool perfmon_capable(void)
256256
return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
257257
}
258258

259+
static inline bool bpf_capable(void)
260+
{
261+
return capable(CAP_BPF) || capable(CAP_SYS_ADMIN);
262+
}
263+
259264
/* audit system wants to get cap info from files as well */
260265
extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
261266

include/uapi/linux/capability.h

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ struct vfs_ns_cap_data {
274274
arbitrary SCSI commands */
275275
/* Allow setting encryption key on loopback filesystem */
276276
/* Allow setting zone reclaim policy */
277+
/* Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility */
277278

278279
#define CAP_SYS_ADMIN 21
279280

@@ -374,7 +375,38 @@ struct vfs_ns_cap_data {
374375

375376
#define CAP_PERFMON 38
376377

377-
#define CAP_LAST_CAP CAP_PERFMON
378+
/*
379+
* CAP_BPF allows the following BPF operations:
380+
* - Creating all types of BPF maps
381+
* - Advanced verifier features
382+
* - Indirect variable access
383+
* - Bounded loops
384+
* - BPF to BPF function calls
385+
* - Scalar precision tracking
386+
* - Larger complexity limits
387+
* - Dead code elimination
388+
* - And potentially other features
389+
* - Loading BPF Type Format (BTF) data
390+
* - Retrieve xlated and JITed code of BPF programs
391+
* - Use bpf_spin_lock() helper
392+
*
393+
* CAP_PERFMON relaxes the verifier checks further:
394+
* - BPF progs can use of pointer-to-integer conversions
395+
* - speculation attack hardening measures are bypassed
396+
* - bpf_probe_read to read arbitrary kernel memory is allowed
397+
* - bpf_trace_printk to print kernel memory is allowed
398+
*
399+
* CAP_SYS_ADMIN is required to use bpf_probe_write_user.
400+
*
401+
* CAP_SYS_ADMIN is required to iterate system wide loaded
402+
* programs, maps, links, BTFs and convert their IDs to file descriptors.
403+
*
404+
* CAP_PERFMON and CAP_BPF are required to load tracing programs.
405+
* CAP_NET_ADMIN and CAP_BPF are required to load networking programs.
406+
*/
407+
#define CAP_BPF 39
408+
409+
#define CAP_LAST_CAP CAP_BPF
378410

379411
#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
380412

security/selinux/include/classmap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
"audit_control", "setfcap"
2828

2929
#define COMMON_CAP2_PERMS "mac_override", "mac_admin", "syslog", \
30-
"wake_alarm", "block_suspend", "audit_read", "perfmon"
30+
"wake_alarm", "block_suspend", "audit_read", "perfmon", "bpf"
3131

32-
#if CAP_LAST_CAP > CAP_PERFMON
32+
#if CAP_LAST_CAP > CAP_BPF
3333
#error New capability defined, please update COMMON_CAP2_PERMS.
3434
#endif
3535

0 commit comments

Comments
 (0)