Prior to Linux 5.8, eBPF access was governed using either CAP_SYS_ADMIN
or uid 0 (root) permissions.
Since then, access control has been fine grained into more capabilities. Current kernel versions use the following capabilities within eBPF:
CAP_BPF
: "Basic" permissions: Load programs, read and write access to maps with known id (maps you have created for example). This permission is required for every bpf system call, unless the caller has CAP_SYS_ADMIN
, or unprivileged mode is enabled.
CAP_NET_ADMIN
: Attach network programs such as XDP or TC.
CAP_PERFMON
: Attach tracing programs such as kprobes or uprobes.
CAP_SYS_ADMIN
: "Full access" mode. Has full access to all programs and maps, no restrictions for program types. Can iterate over maps and find every eBPF map on the system of any program (same for eBPF programs). Can attach and detach all programs.
There is also an unprivileged mode that can work without any of the above permissions, but it is highly restricted in almost every aspect (complexity, maps, program types..). Some distributions may have this disabled by default.
Conclusively, you can access all maps you have a handle to using CAP_BPF
. But in order to actually iterate through every map, CAP_SYS_ADMIN
is required. I'm not sure if it possible to get a handle to arbitrary maps using just CAP_BPF
, as you can't call BPF_MAP_GET_NEXT_ID
. It might be possible to bruteforce ids (IIRC they're just 32bit numbers), but I have not verified this.
Sources: