@@ -8520,43 +8520,52 @@ 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+ static int process_async_func(struct bpf_verifier_env *env, int regno, struct bpf_map **map_ptr,
8524+ int *map_uid, u32 rec_off, enum btf_field_type field_type,
8525+ const char *struct_name)
85258526{
85268527 struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno];
85278528 bool is_const = tnum_is_const(reg->var_off);
85288529 struct bpf_map *map = reg->map_ptr;
85298530 u64 val = reg->var_off.value;
8531+ int *struct_off = (void *)map->record + rec_off;
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 (*struct_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, *struct_off );
85498551 return -EINVAL;
85508552 }
8551- if (meta-> map_ptr) {
8552- verifier_bug(env, "Two map pointers in a timer helper");
8553+ if (* map_ptr) {
8554+ verifier_bug(env, "Two map pointers in a %s helper", struct_name );
85538555 return -EFAULT;
85548556 }
8555- meta-> map_uid = reg->map_uid;
8556- meta-> map_ptr = map;
8557+ * map_uid = reg->map_uid;
8558+ * map_ptr = map;
85578559 return 0;
85588560}
85598561
8562+ static int process_timer_func(struct bpf_verifier_env *env, int regno,
8563+ struct bpf_call_arg_meta *meta)
8564+ {
8565+ return process_async_func(env, regno, &meta->map_ptr, &meta->map_uid,
8566+ offsetof(struct btf_record, timer_off), BPF_TIMER, "bpf_timer");
8567+ }
8568+
85608569static int process_wq_func(struct bpf_verifier_env *env, int regno,
85618570 struct bpf_kfunc_call_arg_meta *meta)
85628571{
0 commit comments