@@ -570,6 +570,8 @@ static const char *reg_type_str(struct bpf_verifier_env *env,
570
570
571
571
if (type & MEM_RDONLY )
572
572
strncpy (prefix , "rdonly_" , 16 );
573
+ if (type & MEM_ALLOC )
574
+ strncpy (prefix , "alloc_" , 16 );
573
575
574
576
snprintf (env -> type_str_buf , TYPE_STR_BUF_LEN , "%s%s%s" ,
575
577
prefix , str [base_type (type )], postfix );
@@ -616,7 +618,7 @@ static void mark_reg_scratched(struct bpf_verifier_env *env, u32 regno)
616
618
617
619
static void mark_stack_slot_scratched (struct bpf_verifier_env * env , u32 spi )
618
620
{
619
- env -> scratched_stack_slots |= 1UL << spi ;
621
+ env -> scratched_stack_slots |= 1ULL << spi ;
620
622
}
621
623
622
624
static 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)
637
639
static void mark_verifier_state_clean (struct bpf_verifier_env * env )
638
640
{
639
641
env -> scratched_regs = 0U ;
640
- env -> scratched_stack_slots = 0UL ;
642
+ env -> scratched_stack_slots = 0ULL ;
641
643
}
642
644
643
645
/* Used for printing the entire verifier state. */
644
646
static void mark_verifier_state_scratched (struct bpf_verifier_env * env )
645
647
{
646
648
env -> scratched_regs = ~0U ;
647
- env -> scratched_stack_slots = ~0UL ;
649
+ env -> scratched_stack_slots = ~0ULL ;
648
650
}
649
651
650
652
/* 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,
3969
3971
}
3970
3972
#endif
3971
3973
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 )
3974
3977
{
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.
3977
3980
*/
3978
3981
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 );
3982
3985
return - EACCES ;
3983
3986
}
3984
3987
3985
3988
if (!tnum_is_const (reg -> var_off ) || reg -> var_off .value ) {
3986
3989
char tn_buf [48 ];
3987
3990
3988
3991
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 );
3990
3994
return - EACCES ;
3991
3995
}
3992
3996
3993
3997
return 0 ;
3994
3998
}
3995
3999
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
+
3996
4006
static int __check_buffer_access (struct bpf_verifier_env * env ,
3997
4007
const char * buf_info ,
3998
4008
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
4437
4447
return - EACCES ;
4438
4448
}
4439
4449
4440
- err = check_ctx_reg (env , reg , regno );
4450
+ err = check_ptr_off_reg (env , reg , regno );
4441
4451
if (err < 0 )
4442
4452
return err ;
4443
4453
@@ -5127,6 +5137,7 @@ static const struct bpf_reg_types mem_types = {
5127
5137
PTR_TO_MAP_KEY ,
5128
5138
PTR_TO_MAP_VALUE ,
5129
5139
PTR_TO_MEM ,
5140
+ PTR_TO_MEM | MEM_ALLOC ,
5130
5141
PTR_TO_BUF ,
5131
5142
},
5132
5143
};
@@ -5144,7 +5155,7 @@ static const struct bpf_reg_types int_ptr_types = {
5144
5155
static const struct bpf_reg_types fullsock_types = { .types = { PTR_TO_SOCKET } };
5145
5156
static const struct bpf_reg_types scalar_types = { .types = { SCALAR_VALUE } };
5146
5157
static 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 } };
5148
5159
static const struct bpf_reg_types const_map_ptr_types = { .types = { CONST_PTR_TO_MAP } };
5149
5160
static const struct bpf_reg_types btf_ptr_types = { .types = { PTR_TO_BTF_ID } };
5150
5161
static 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,
5244
5255
kernel_type_name (btf_vmlinux , * arg_btf_id ));
5245
5256
return - EACCES ;
5246
5257
}
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
- }
5253
5258
}
5254
5259
5255
5260
return 0 ;
@@ -5304,10 +5309,33 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
5304
5309
if (err )
5305
5310
return err ;
5306
5311
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 );
5309
5336
if (err < 0 )
5310
5337
return err ;
5338
+ break ;
5311
5339
}
5312
5340
5313
5341
skip_type_check :
@@ -9507,9 +9535,13 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
9507
9535
return 0 ;
9508
9536
}
9509
9537
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 );
9512
9543
9544
+ if (insn -> src_reg == BPF_PSEUDO_BTF_ID ) {
9513
9545
dst_reg -> type = aux -> btf_var .reg_type ;
9514
9546
switch (base_type (dst_reg -> type )) {
9515
9547
case PTR_TO_MEM :
@@ -9547,7 +9579,6 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
9547
9579
}
9548
9580
9549
9581
map = env -> used_maps [aux -> map_index ];
9550
- mark_reg_known_zero (env , regs , insn -> dst_reg );
9551
9582
dst_reg -> map_ptr = map ;
9552
9583
9553
9584
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)
9651
9682
return err ;
9652
9683
}
9653
9684
9654
- err = check_ctx_reg (env , & regs [ctx_reg ], ctx_reg );
9685
+ err = check_ptr_off_reg (env , & regs [ctx_reg ], ctx_reg );
9655
9686
if (err < 0 )
9656
9687
return err ;
9657
9688
0 commit comments