@@ -249,6 +249,11 @@ static bool type_is_pkt_pointer(enum bpf_reg_type type)
249
249
type == PTR_TO_PACKET_META ;
250
250
}
251
251
252
+ static bool reg_type_may_be_null (enum bpf_reg_type type )
253
+ {
254
+ return type == PTR_TO_MAP_VALUE_OR_NULL ;
255
+ }
256
+
252
257
/* string representation of 'enum bpf_reg_type' */
253
258
static const char * const reg_type_str [] = {
254
259
[NOT_INIT ] = "?" ,
@@ -3599,12 +3604,10 @@ static void reg_combine_min_max(struct bpf_reg_state *true_src,
3599
3604
}
3600
3605
}
3601
3606
3602
- static void mark_map_reg (struct bpf_reg_state * regs , u32 regno , u32 id ,
3603
- bool is_null )
3607
+ static void mark_ptr_or_null_reg (struct bpf_reg_state * reg , u32 id ,
3608
+ bool is_null )
3604
3609
{
3605
- struct bpf_reg_state * reg = & regs [regno ];
3606
-
3607
- if (reg -> type == PTR_TO_MAP_VALUE_OR_NULL && reg -> id == id ) {
3610
+ if (reg_type_may_be_null (reg -> type ) && reg -> id == id ) {
3608
3611
/* Old offset (both fixed and variable parts) should
3609
3612
* have been known-zero, because we don't allow pointer
3610
3613
* arithmetic on pointers that might be NULL.
@@ -3617,11 +3620,13 @@ static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id,
3617
3620
}
3618
3621
if (is_null ) {
3619
3622
reg -> type = SCALAR_VALUE ;
3620
- } else if (reg -> map_ptr -> inner_map_meta ) {
3621
- reg -> type = CONST_PTR_TO_MAP ;
3622
- reg -> map_ptr = reg -> map_ptr -> inner_map_meta ;
3623
- } else {
3624
- reg -> type = PTR_TO_MAP_VALUE ;
3623
+ } else if (reg -> type == PTR_TO_MAP_VALUE_OR_NULL ) {
3624
+ if (reg -> map_ptr -> inner_map_meta ) {
3625
+ reg -> type = CONST_PTR_TO_MAP ;
3626
+ reg -> map_ptr = reg -> map_ptr -> inner_map_meta ;
3627
+ } else {
3628
+ reg -> type = PTR_TO_MAP_VALUE ;
3629
+ }
3625
3630
}
3626
3631
/* We don't need id from this point onwards anymore, thus we
3627
3632
* should better reset it, so that state pruning has chances
@@ -3634,23 +3639,23 @@ static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id,
3634
3639
/* The logic is similar to find_good_pkt_pointers(), both could eventually
3635
3640
* be folded together at some point.
3636
3641
*/
3637
- static void mark_map_regs (struct bpf_verifier_state * vstate , u32 regno ,
3638
- bool is_null )
3642
+ static void mark_ptr_or_null_regs (struct bpf_verifier_state * vstate , u32 regno ,
3643
+ bool is_null )
3639
3644
{
3640
3645
struct bpf_func_state * state = vstate -> frame [vstate -> curframe ];
3641
3646
struct bpf_reg_state * reg , * regs = state -> regs ;
3642
3647
u32 id = regs [regno ].id ;
3643
3648
int i , j ;
3644
3649
3645
3650
for (i = 0 ; i < MAX_BPF_REG ; i ++ )
3646
- mark_map_reg ( regs , i , id , is_null );
3651
+ mark_ptr_or_null_reg ( & regs [ i ] , id , is_null );
3647
3652
3648
3653
for (j = 0 ; j <= vstate -> curframe ; j ++ ) {
3649
3654
state = vstate -> frame [j ];
3650
3655
bpf_for_each_spilled_reg (i , state , reg ) {
3651
3656
if (!reg )
3652
3657
continue ;
3653
- mark_map_reg ( & state -> stack [ i ]. spilled_ptr , 0 , id , is_null );
3658
+ mark_ptr_or_null_reg ( reg , id , is_null );
3654
3659
}
3655
3660
}
3656
3661
}
@@ -3852,12 +3857,14 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
3852
3857
/* detect if R == 0 where R is returned from bpf_map_lookup_elem() */
3853
3858
if (BPF_SRC (insn -> code ) == BPF_K &&
3854
3859
insn -> imm == 0 && (opcode == BPF_JEQ || opcode == BPF_JNE ) &&
3855
- dst_reg -> type == PTR_TO_MAP_VALUE_OR_NULL ) {
3856
- /* Mark all identical map registers in each branch as either
3860
+ reg_type_may_be_null ( dst_reg -> type ) ) {
3861
+ /* Mark all identical registers in each branch as either
3857
3862
* safe or unknown depending R == 0 or R != 0 conditional.
3858
3863
*/
3859
- mark_map_regs (this_branch , insn -> dst_reg , opcode == BPF_JNE );
3860
- mark_map_regs (other_branch , insn -> dst_reg , opcode == BPF_JEQ );
3864
+ mark_ptr_or_null_regs (this_branch , insn -> dst_reg ,
3865
+ opcode == BPF_JNE );
3866
+ mark_ptr_or_null_regs (other_branch , insn -> dst_reg ,
3867
+ opcode == BPF_JEQ );
3861
3868
} else if (!try_match_pkt_pointers (insn , dst_reg , & regs [insn -> src_reg ],
3862
3869
this_branch , other_branch ) &&
3863
3870
is_pointer_value (env , insn -> dst_reg )) {
0 commit comments