@@ -2813,6 +2813,31 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env,
2813
2813
}
2814
2814
}
2815
2815
2816
+ static void mark_all_scalars_imprecise (struct bpf_verifier_env * env , struct bpf_verifier_state * st )
2817
+ {
2818
+ struct bpf_func_state * func ;
2819
+ struct bpf_reg_state * reg ;
2820
+ int i , j ;
2821
+
2822
+ for (i = 0 ; i <= st -> curframe ; i ++ ) {
2823
+ func = st -> frame [i ];
2824
+ for (j = 0 ; j < BPF_REG_FP ; j ++ ) {
2825
+ reg = & func -> regs [j ];
2826
+ if (reg -> type != SCALAR_VALUE )
2827
+ continue ;
2828
+ reg -> precise = false;
2829
+ }
2830
+ for (j = 0 ; j < func -> allocated_stack / BPF_REG_SIZE ; j ++ ) {
2831
+ if (!is_spilled_reg (& func -> stack [j ]))
2832
+ continue ;
2833
+ reg = & func -> stack [j ].spilled_ptr ;
2834
+ if (reg -> type != SCALAR_VALUE )
2835
+ continue ;
2836
+ reg -> precise = false;
2837
+ }
2838
+ }
2839
+ }
2840
+
2816
2841
/*
2817
2842
* __mark_chain_precision() backtracks BPF program instruction sequence and
2818
2843
* chain of verifier states making sure that register *regno* (if regno >= 0)
@@ -2891,6 +2916,14 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env,
2891
2916
* be imprecise. If any child state does require this register to be precise,
2892
2917
* we'll mark it precise later retroactively during precise markings
2893
2918
* propagation from child state to parent states.
2919
+ *
2920
+ * Skipping precise marking setting in current state is a mild version of
2921
+ * relying on the above observation. But we can utilize this property even
2922
+ * more aggressively by proactively forgetting any precise marking in the
2923
+ * current state (which we inherited from the parent state), right before we
2924
+ * checkpoint it and branch off into new child state. This is done by
2925
+ * mark_all_scalars_imprecise() to hopefully get more permissive and generic
2926
+ * finalized states which help in short circuiting more future states.
2894
2927
*/
2895
2928
static int __mark_chain_precision (struct bpf_verifier_env * env , int frame , int regno ,
2896
2929
int spi )
@@ -12296,6 +12329,10 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
12296
12329
env -> prev_jmps_processed = env -> jmps_processed ;
12297
12330
env -> prev_insn_processed = env -> insn_processed ;
12298
12331
12332
+ /* forget precise markings we inherited, see __mark_chain_precision */
12333
+ if (env -> bpf_capable )
12334
+ mark_all_scalars_imprecise (env , cur );
12335
+
12299
12336
/* add new state to the head of linked list */
12300
12337
new = & new_sl -> state ;
12301
12338
err = copy_verifier_state (new , cur );
0 commit comments