@@ -8520,8 +8520,10 @@ static int process_spin_lock(struct bpf_verifier_env *env, int regno, int flags)
85208520 return 0;
85218521}
85228522
8523- static int process_timer_func(struct bpf_verifier_env *env, int regno,
8524- struct bpf_call_arg_meta *meta)
8523+ /* Check if @regno is a pointer to a specific field in a map value */
8524+ static int check_map_field_pointer(struct bpf_verifier_env *env, u32 regno,
8525+ enum btf_field_type field_type, u32 field_off,
8526+ const char *struct_name)
85258527{
85268528 struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno];
85278529 bool is_const = tnum_is_const(reg->var_off);
@@ -8530,26 +8532,40 @@ static int process_timer_func(struct bpf_verifier_env *env, int regno,
85308532
85318533 if (!is_const) {
85328534 verbose(env,
8533- "R%d doesn't have constant offset. bpf_timer has to be at the constant offset\n",
8534- regno);
8535+ "R%d doesn't have constant offset. %s has to be at the constant offset\n",
8536+ regno, struct_name );
85358537 return -EINVAL;
85368538 }
85378539 if (!map->btf) {
8538- verbose(env, "map '%s' has to have BTF in order to use bpf_timer \n",
8539- map->name );
8540+ verbose(env, "map '%s' has to have BTF in order to use %s \n", map->name ,
8541+ struct_name );
85408542 return -EINVAL;
85418543 }
8542- if (!btf_record_has_field(map->record, BPF_TIMER )) {
8543- verbose(env, "map '%s' has no valid bpf_timer \n", map->name);
8544+ if (!btf_record_has_field(map->record, field_type )) {
8545+ verbose(env, "map '%s' has no valid %s \n", map->name, struct_name );
85448546 return -EINVAL;
85458547 }
8546- if (map->record->timer_off != val + reg->off) {
8547- verbose(env, "off %lld doesn't point to 'struct bpf_timer ' that is at %d\n",
8548- val + reg->off, map->record->timer_off );
8548+ if (field_off != val + reg->off) {
8549+ verbose(env, "off %lld doesn't point to 'struct %s ' that is at %d\n",
8550+ val + reg->off, struct_name, field_off );
85498551 return -EINVAL;
85508552 }
8553+ return 0;
8554+ }
8555+
8556+ static int process_timer_func(struct bpf_verifier_env *env, int regno,
8557+ struct bpf_call_arg_meta *meta)
8558+ {
8559+ struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno];
8560+ struct bpf_map *map = reg->map_ptr;
8561+ int err;
8562+
8563+ err = check_map_field_pointer(env, regno, BPF_TIMER, map->record->timer_off, "bpf_timer");
8564+ if (err)
8565+ return err;
8566+
85518567 if (meta->map_ptr) {
8552- verifier_bug(env, "Two map pointers in a timer helper");
8568+ verifier_bug(env, "Two map pointers in a bpf_timer helper");
85538569 return -EFAULT;
85548570 }
85558571 if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
0 commit comments