1

I have read that there are some capabilities that are broken out of CAP_SYS_ADMIN specifically CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON etc. I also read that data structures called maps are used to store data and that other eBPF programs can read data in these structures. From a security point of view this is bad if sensitive content is in these maps.

Is CAP_SYS_ADMIN required to enumerate and read all program maps data or can a program with CAP_BPF read other program maps and modify maps data too? If it is limited maps read and write, can someone describe which maps they are with CAP_BPF and CAP_NET_ADMIN?

UndercoverDog
  • 612
  • 2
  • 17

1 Answers1

1

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:

Nummer378
  • 11
  • 3