@@ -570,6 +570,8 @@ static const char *reg_type_str(struct bpf_verifier_env *env,
570570
571571 if (type & MEM_RDONLY )
572572 strncpy (prefix , "rdonly_" , 16 );
573+ if (type & MEM_ALLOC )
574+ strncpy (prefix , "alloc_" , 16 );
573575
574576 snprintf (env -> type_str_buf , TYPE_STR_BUF_LEN , "%s%s%s" ,
575577 prefix , str [base_type (type )], postfix );
@@ -616,7 +618,7 @@ static void mark_reg_scratched(struct bpf_verifier_env *env, u32 regno)
616618
617619static void mark_stack_slot_scratched (struct bpf_verifier_env * env , u32 spi )
618620{
619- env -> scratched_stack_slots |= 1UL << spi ;
621+ env -> scratched_stack_slots |= 1ULL << spi ;
620622}
621623
622624static bool reg_scratched (const struct bpf_verifier_env * env , u32 regno )
@@ -637,14 +639,14 @@ static bool verifier_state_scratched(const struct bpf_verifier_env *env)
637639static void mark_verifier_state_clean (struct bpf_verifier_env * env )
638640{
639641 env -> scratched_regs = 0U ;
640- env -> scratched_stack_slots = 0UL ;
642+ env -> scratched_stack_slots = 0ULL ;
641643}
642644
643645/* Used for printing the entire verifier state. */
644646static void mark_verifier_state_scratched (struct bpf_verifier_env * env )
645647{
646648 env -> scratched_regs = ~0U ;
647- env -> scratched_stack_slots = ~0UL ;
649+ env -> scratched_stack_slots = ~0ULL ;
648650}
649651
650652/* The reg state of a pointer or a bounded scalar was saved when
@@ -3969,30 +3971,38 @@ static int get_callee_stack_depth(struct bpf_verifier_env *env,
39693971}
39703972#endif
39713973
3972- int check_ctx_reg (struct bpf_verifier_env * env ,
3973- const struct bpf_reg_state * reg , int regno )
3974+ static int __check_ptr_off_reg (struct bpf_verifier_env * env ,
3975+ const struct bpf_reg_state * reg , int regno ,
3976+ bool fixed_off_ok )
39743977{
3975- /* Access to ctx or passing it to a helper is only allowed in
3976- * its original, unmodified form.
3978+ /* Access to this pointer-typed register or passing it to a helper
3979+ * is only allowed in its original, unmodified form.
39773980 */
39783981
3979- if (reg -> off ) {
3980- verbose (env , "dereference of modified ctx ptr R%d off=%d disallowed\n" ,
3981- regno , reg -> off );
3982+ if (! fixed_off_ok && reg -> off ) {
3983+ verbose (env , "dereference of modified %s ptr R%d off=%d disallowed\n" ,
3984+ reg_type_str ( env , reg -> type ), regno , reg -> off );
39823985 return - EACCES ;
39833986 }
39843987
39853988 if (!tnum_is_const (reg -> var_off ) || reg -> var_off .value ) {
39863989 char tn_buf [48 ];
39873990
39883991 tnum_strn (tn_buf , sizeof (tn_buf ), reg -> var_off );
3989- verbose (env , "variable ctx access var_off=%s disallowed\n" , tn_buf );
3992+ verbose (env , "variable %s access var_off=%s disallowed\n" ,
3993+ reg_type_str (env , reg -> type ), tn_buf );
39903994 return - EACCES ;
39913995 }
39923996
39933997 return 0 ;
39943998}
39953999
4000+ int check_ptr_off_reg (struct bpf_verifier_env * env ,
4001+ const struct bpf_reg_state * reg , int regno )
4002+ {
4003+ return __check_ptr_off_reg (env , reg , regno , false);
4004+ }
4005+
39964006static int __check_buffer_access (struct bpf_verifier_env * env ,
39974007 const char * buf_info ,
39984008 const struct bpf_reg_state * reg ,
@@ -4437,7 +4447,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
44374447 return - EACCES ;
44384448 }
44394449
4440- err = check_ctx_reg (env , reg , regno );
4450+ err = check_ptr_off_reg (env , reg , regno );
44414451 if (err < 0 )
44424452 return err ;
44434453
@@ -5127,6 +5137,7 @@ static const struct bpf_reg_types mem_types = {
51275137 PTR_TO_MAP_KEY ,
51285138 PTR_TO_MAP_VALUE ,
51295139 PTR_TO_MEM ,
5140+ PTR_TO_MEM | MEM_ALLOC ,
51305141 PTR_TO_BUF ,
51315142 },
51325143};
@@ -5144,7 +5155,7 @@ static const struct bpf_reg_types int_ptr_types = {
51445155static const struct bpf_reg_types fullsock_types = { .types = { PTR_TO_SOCKET } };
51455156static const struct bpf_reg_types scalar_types = { .types = { SCALAR_VALUE } };
51465157static const struct bpf_reg_types context_types = { .types = { PTR_TO_CTX } };
5147- static const struct bpf_reg_types alloc_mem_types = { .types = { PTR_TO_MEM } };
5158+ static const struct bpf_reg_types alloc_mem_types = { .types = { PTR_TO_MEM | MEM_ALLOC } };
51485159static const struct bpf_reg_types const_map_ptr_types = { .types = { CONST_PTR_TO_MAP } };
51495160static const struct bpf_reg_types btf_ptr_types = { .types = { PTR_TO_BTF_ID } };
51505161static const struct bpf_reg_types spin_lock_types = { .types = { PTR_TO_MAP_VALUE } };
@@ -5244,12 +5255,6 @@ static int check_reg_type(struct bpf_verifier_env *env, u32 regno,
52445255 kernel_type_name (btf_vmlinux , * arg_btf_id ));
52455256 return - EACCES ;
52465257 }
5247-
5248- if (!tnum_is_const (reg -> var_off ) || reg -> var_off .value ) {
5249- verbose (env , "R%d is a pointer to in-kernel struct with non-zero offset\n" ,
5250- regno );
5251- return - EACCES ;
5252- }
52535258 }
52545259
52555260 return 0 ;
@@ -5304,10 +5309,33 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
53045309 if (err )
53055310 return err ;
53065311
5307- if (type == PTR_TO_CTX ) {
5308- err = check_ctx_reg (env , reg , regno );
5312+ switch ((u32 )type ) {
5313+ case SCALAR_VALUE :
5314+ /* Pointer types where reg offset is explicitly allowed: */
5315+ case PTR_TO_PACKET :
5316+ case PTR_TO_PACKET_META :
5317+ case PTR_TO_MAP_KEY :
5318+ case PTR_TO_MAP_VALUE :
5319+ case PTR_TO_MEM :
5320+ case PTR_TO_MEM | MEM_RDONLY :
5321+ case PTR_TO_MEM | MEM_ALLOC :
5322+ case PTR_TO_BUF :
5323+ case PTR_TO_BUF | MEM_RDONLY :
5324+ case PTR_TO_STACK :
5325+ /* Some of the argument types nevertheless require a
5326+ * zero register offset.
5327+ */
5328+ if (arg_type == ARG_PTR_TO_ALLOC_MEM )
5329+ goto force_off_check ;
5330+ break ;
5331+ /* All the rest must be rejected: */
5332+ default :
5333+ force_off_check :
5334+ err = __check_ptr_off_reg (env , reg , regno ,
5335+ type == PTR_TO_BTF_ID );
53095336 if (err < 0 )
53105337 return err ;
5338+ break ;
53115339 }
53125340
53135341skip_type_check :
@@ -9507,9 +9535,13 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
95079535 return 0 ;
95089536 }
95099537
9510- if (insn -> src_reg == BPF_PSEUDO_BTF_ID ) {
9511- mark_reg_known_zero (env , regs , insn -> dst_reg );
9538+ /* All special src_reg cases are listed below. From this point onwards
9539+ * we either succeed and assign a corresponding dst_reg->type after
9540+ * zeroing the offset, or fail and reject the program.
9541+ */
9542+ mark_reg_known_zero (env , regs , insn -> dst_reg );
95129543
9544+ if (insn -> src_reg == BPF_PSEUDO_BTF_ID ) {
95139545 dst_reg -> type = aux -> btf_var .reg_type ;
95149546 switch (base_type (dst_reg -> type )) {
95159547 case PTR_TO_MEM :
@@ -9547,7 +9579,6 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
95479579 }
95489580
95499581 map = env -> used_maps [aux -> map_index ];
9550- mark_reg_known_zero (env , regs , insn -> dst_reg );
95519582 dst_reg -> map_ptr = map ;
95529583
95539584 if (insn -> src_reg == BPF_PSEUDO_MAP_VALUE ||
@@ -9651,7 +9682,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
96519682 return err ;
96529683 }
96539684
9654- err = check_ctx_reg (env , & regs [ctx_reg ], ctx_reg );
9685+ err = check_ptr_off_reg (env , & regs [ctx_reg ], ctx_reg );
96559686 if (err < 0 )
96569687 return err ;
96579688
0 commit comments