History

bpf: Implement CAP_BPF

Implement permissions as stated in uapi/linux/capability.h In order to do that the verifier allow_ptr_leaks flag is split into four flags and they are set as: env->allow_ptr_leaks = bpf_allow_ptr_leaks(); env->bypass_spec_v1 = bpf_bypass_spec_v1(); env->bypass_spec_v4 = bpf_bypass_spec_v4(); env->bpf_capable = bpf_capable(); The first three currently equivalent to perfmon_capable(), since leaking kernel pointers and reading kernel memory via side channel attacks is roughly equivalent to reading kernel memory with cap_perfmon. 'bpf_capable' enables bounded loops, precision tracking, bpf to bpf calls and other verifier features. 'allow_ptr_leaks' enable ptr leaks, ptr conversions, subtraction of pointers. 'bypass_spec_v1' disables speculative analysis in the verifier, run time mitigations in bpf array, and enables indirect variable access in bpf programs. 'bypass_spec_v4' disables emission of sanitation code by the verifier. That means that the networking BPF program loaded with CAP_BPF + CAP_NET_ADMIN will have speculative checks done by the verifier and other spectre mitigation applied. Such networking BPF program will not be able to leak kernel pointers and will not be able to access arbitrary kernel memory.

Alexei Starovoitov committed 6 years ago

Commit 2c78ee81 parent a17b53c19 files · +134 −60Browse files

Showing the changes to include/linux (2 of 19 files). Show all

Unified · Split

2 files
  1. include/linux/bpf.h +17 −1
  2. include/linux/bpf_verifier.h +3 −0
include/linux/bpf.h+17−1
@@ -19,6 +19,7 @@ · 18 unmodified lines
1919 #include <linux/mutex.h>
2020 #include <linux/module.h>
2121 #include <linux/kallsyms.h>
22+#include <linux/capability.h>
2223
2324 struct bpf_verifier_env;
2425 struct bpf_verifier_log;
@@ -119,7 +120,7 @@ struct bpf_map { · 94 unmodified lines
119120 struct bpf_map_memory memory;
120121 char name[BPF_OBJ_NAME_LEN];
121122 u32 btf_vmlinux_value_type_id;
122− bool unpriv_array;
123+ bool bypass_spec_v1;
123124 bool frozen; /* write-once; write-protected by freeze_mutex */
124125 /* 22 bytes hole */
125126
@@ -1095,6 +1096,21 @@ struct bpf_map *bpf_map_get_curr_or_next(u32 *id); · 969 unmodified lines
10951096
10961097 extern int sysctl_unprivileged_bpf_disabled;
10971098
1099+static inline bool bpf_allow_ptr_leaks(void)
1100+{
1101+ return perfmon_capable();
1102+}
1103+
1104+static inline bool bpf_bypass_spec_v1(void)
1105+{
1106+ return perfmon_capable();
1107+}
1108+
1109+static inline bool bpf_bypass_spec_v4(void)
1110+{
1111+ return perfmon_capable();
1112+}
1113+
10981114 int bpf_map_new_fd(struct bpf_map *map, int flags);
10991115 int bpf_prog_new_fd(struct bpf_prog *prog);
11001116
include/linux/bpf_verifier.h+3−0
@@ -375,6 +375,9 @@ struct bpf_verifier_env { · 374 unmodified lines
375375 u32 used_map_cnt; /* number of used maps */
376376 u32 id_gen; /* used to generate unique reg IDs */
377377 bool allow_ptr_leaks;
378+ bool bpf_capable;
379+ bool bypass_spec_v1;
380+ bool bypass_spec_v4;
378381 bool seen_direct_write;
379382 struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */
380383 const struct bpf_line_info *prev_linfo;