malicious bpf program may try to force the verifier to remember a lot of distinct verifier states. Put a limit to number of per-insn 'struct bpf_verifier_state'. Note that hitting the limit doesn't reject the program. It potentially makes the verifier do more steps to analyze the program. It means that malicious programs will hit BPF_COMPLEXITY_LIMIT_INSNS sooner instead of spending cpu time walking long link list. The limit of BPF_COMPLEXITY_LIMIT_STATES==64 affects cilium progs with slight increase in number of "steps" it takes to successfully verify the programs: before after bpf_lb-DLB_L3.o 1940 1940 bpf_lb-DLB_L4.o 3089 3089 bpf_lb-DUNKNOWN.o 1065 1065 bpf_lxc-DDROP_ALL.o 28052 | 28162 bpf_lxc-DUNKNOWN.o 35487 | 35541 bpf_netdev.o 10864 10864 bpf_overlay.o 6643 6643 bpf_lcx_jit.o 38437 38437 But it also makes malicious program to be rejected in 0.4 seconds vs 6.5 Hence apply this limit to unprivileged programs only.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -175,6 +175,7 @@ struct bpf_verifier_stack_elem { · 174 unmodified lines | ||
| 175 | 175 | |
| 176 | 176 | #define BPF_COMPLEXITY_LIMIT_INSNS 131072 |
| 177 | 177 | #define BPF_COMPLEXITY_LIMIT_STACK 1024 |
| 178 | +#define BPF_COMPLEXITY_LIMIT_STATES 64 | |
| 178 | 179 | |
| 179 | 180 | #define BPF_MAP_PTR_UNPRIV 1UL |
| 180 | 181 | #define BPF_MAP_PTR_POISON ((void *)((0xeB9FUL << 1) + \ |
| @@ -5047,7 +5048,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) · 4866 unmodified lines | ||
| 5047 | 5048 | struct bpf_verifier_state_list *new_sl; |
| 5048 | 5049 | struct bpf_verifier_state_list *sl; |
| 5049 | 5050 | struct bpf_verifier_state *cur = env->cur_state, *new; |
| 5050 | − int i, j, err; | |
| 5051 | + int i, j, err, states_cnt = 0; | |
| 5051 | 5052 | |
| 5052 | 5053 | sl = env->explored_states[insn_idx]; |
| 5053 | 5054 | if (!sl) |
| @@ -5074,8 +5075,12 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) · 20 unmodified lines | ||
| 5074 | 5075 | return 1; |
| 5075 | 5076 | } |
| 5076 | 5077 | sl = sl->next; |
| 5078 | + states_cnt++; | |
| 5077 | 5079 | } |
| 5078 | 5080 | |
| 5081 | + if (!env->allow_ptr_leaks && states_cnt > BPF_COMPLEXITY_LIMIT_STATES) | |
| 5082 | + return 0; | |
| 5083 | + | |
| 5079 | 5084 | /* there were no equivalent states, remember current one. |
| 5080 | 5085 | * technically the current state is not proven to be safe yet, |
| 5081 | 5086 | * but it will either reach outer most bpf_exit (which means it's safe) |