Skip to content

Commit 98c4fd2

Browse files
mykyta5Alexei Starovoitov
authored andcommitted
bpf: Introduce struct bpf_map_desc in verifier
Introduce struct bpf_map_desc to hold bpf_map pointer and map uid. Use this struct in both bpf_call_arg_meta and bpf_kfunc_call_arg_meta instead of having different representations: - bpf_call_arg_meta had separate map_ptr and map_uid fields - bpf_kfunc_call_arg_meta had an anonymous inline struct This unifies the map fields layout across both metadata structures, making the code more consistent and preparing for further refactoring of map field pointer validation. Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> Link: https://lore.kernel.org/r/20260130-verif_special_fields-v2-1-2c59e637da7d@meta.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent c7fbf8d commit 98c4fd2

1 file changed

Lines changed: 40 additions & 39 deletions

File tree

kernel/bpf/verifier.c

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,13 @@ static bool bpf_pseudo_kfunc_call(const struct bpf_insn *insn)
272272
insn->src_reg == BPF_PSEUDO_KFUNC_CALL;
273273
}
274274

275+
struct bpf_map_desc {
276+
struct bpf_map *ptr;
277+
int uid;
278+
};
279+
275280
struct bpf_call_arg_meta {
276-
struct bpf_map *map_ptr;
281+
struct bpf_map_desc map;
277282
bool raw_mode;
278283
bool pkt_access;
279284
u8 release_regno;
@@ -283,7 +288,6 @@ struct bpf_call_arg_meta {
283288
u64 msize_max_value;
284289
int ref_obj_id;
285290
int dynptr_id;
286-
int map_uid;
287291
int func_id;
288292
struct btf *btf;
289293
u32 btf_id;
@@ -351,10 +355,7 @@ struct bpf_kfunc_call_arg_meta {
351355
u8 spi;
352356
u8 frameno;
353357
} iter;
354-
struct {
355-
struct bpf_map *ptr;
356-
int uid;
357-
} map;
358+
struct bpf_map_desc map;
358359
u64 mem_size;
359360
};
360361

@@ -8666,16 +8667,16 @@ static int process_timer_func(struct bpf_verifier_env *env, int regno,
86668667
if (err)
86678668
return err;
86688669

8669-
if (meta->map_ptr) {
8670+
if (meta->map.ptr) {
86708671
verifier_bug(env, "Two map pointers in a timer helper");
86718672
return -EFAULT;
86728673
}
86738674
if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
86748675
verbose(env, "bpf_timer cannot be used for PREEMPT_RT.\n");
86758676
return -EOPNOTSUPP;
86768677
}
8677-
meta->map_uid = reg->map_uid;
8678-
meta->map_ptr = map;
8678+
meta->map.uid = reg->map_uid;
8679+
meta->map.ptr = map;
86798680
return 0;
86808681
}
86818682

@@ -8739,7 +8740,7 @@ static int process_kptr_func(struct bpf_verifier_env *env, int regno,
87398740
return -EINVAL;
87408741
}
87418742
rec = map_ptr->record;
8742-
meta->map_ptr = map_ptr;
8743+
meta->map.ptr = map_ptr;
87438744
}
87448745

87458746
if (!tnum_is_const(reg->var_off)) {
@@ -9246,13 +9247,13 @@ static int resolve_map_arg_type(struct bpf_verifier_env *env,
92469247
const struct bpf_call_arg_meta *meta,
92479248
enum bpf_arg_type *arg_type)
92489249
{
9249-
if (!meta->map_ptr) {
9250+
if (!meta->map.ptr) {
92509251
/* kernel subsystem misconfigured verifier */
92519252
verifier_bug(env, "invalid map_ptr to access map->type");
92529253
return -EFAULT;
92539254
}
92549255

9255-
switch (meta->map_ptr->map_type) {
9256+
switch (meta->map.ptr->map_type) {
92569257
case BPF_MAP_TYPE_SOCKMAP:
92579258
case BPF_MAP_TYPE_SOCKHASH:
92589259
if (*arg_type == ARG_PTR_TO_MAP_VALUE) {
@@ -9906,7 +9907,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
99069907
switch (base_type(arg_type)) {
99079908
case ARG_CONST_MAP_PTR:
99089909
/* bpf_map_xxx(map_ptr) call: remember that map_ptr */
9909-
if (meta->map_ptr) {
9910+
if (meta->map.ptr) {
99109911
/* Use map_uid (which is unique id of inner map) to reject:
99119912
* inner_map1 = bpf_map_lookup_elem(outer_map, key1)
99129913
* inner_map2 = bpf_map_lookup_elem(outer_map, key2)
@@ -9919,23 +9920,23 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
99199920
*
99209921
* Comparing map_ptr is enough to distinguish normal and outer maps.
99219922
*/
9922-
if (meta->map_ptr != reg->map_ptr ||
9923-
meta->map_uid != reg->map_uid) {
9923+
if (meta->map.ptr != reg->map_ptr ||
9924+
meta->map.uid != reg->map_uid) {
99249925
verbose(env,
99259926
"timer pointer in R1 map_uid=%d doesn't match map pointer in R2 map_uid=%d\n",
9926-
meta->map_uid, reg->map_uid);
9927+
meta->map.uid, reg->map_uid);
99279928
return -EINVAL;
99289929
}
99299930
}
9930-
meta->map_ptr = reg->map_ptr;
9931-
meta->map_uid = reg->map_uid;
9931+
meta->map.ptr = reg->map_ptr;
9932+
meta->map.uid = reg->map_uid;
99329933
break;
99339934
case ARG_PTR_TO_MAP_KEY:
99349935
/* bpf_map_xxx(..., map_ptr, ..., key) call:
99359936
* check that [key, key + map->key_size) are within
99369937
* stack limits and initialized
99379938
*/
9938-
if (!meta->map_ptr) {
9939+
if (!meta->map.ptr) {
99399940
/* in function declaration map_ptr must come before
99409941
* map_key, so that it's verified and known before
99419942
* we have to check map_key here. Otherwise it means
@@ -9944,11 +9945,11 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
99449945
verifier_bug(env, "invalid map_ptr to access map->key");
99459946
return -EFAULT;
99469947
}
9947-
key_size = meta->map_ptr->key_size;
9948+
key_size = meta->map.ptr->key_size;
99489949
err = check_helper_mem_access(env, regno, key_size, BPF_READ, false, NULL);
99499950
if (err)
99509951
return err;
9951-
if (can_elide_value_nullness(meta->map_ptr->map_type)) {
9952+
if (can_elide_value_nullness(meta->map.ptr->map_type)) {
99529953
err = get_constant_map_key(env, reg, key_size, &meta->const_map_key);
99539954
if (err < 0) {
99549955
meta->const_map_key = -1;
@@ -9966,13 +9967,13 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
99669967
/* bpf_map_xxx(..., map_ptr, ..., value) call:
99679968
* check [value, value + map->value_size) validity
99689969
*/
9969-
if (!meta->map_ptr) {
9970+
if (!meta->map.ptr) {
99709971
/* kernel subsystem misconfigured verifier */
99719972
verifier_bug(env, "invalid map_ptr to access map->value");
99729973
return -EFAULT;
99739974
}
99749975
meta->raw_mode = arg_type & MEM_UNINIT;
9975-
err = check_helper_mem_access(env, regno, meta->map_ptr->value_size,
9976+
err = check_helper_mem_access(env, regno, meta->map.ptr->value_size,
99769977
arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ,
99779978
false, meta);
99789979
break;
@@ -11310,7 +11311,7 @@ record_func_map(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
1131011311
int func_id, int insn_idx)
1131111312
{
1131211313
struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
11313-
struct bpf_map *map = meta->map_ptr;
11314+
struct bpf_map *map = meta->map.ptr;
1131411315

1131511316
if (func_id != BPF_FUNC_tail_call &&
1131611317
func_id != BPF_FUNC_map_lookup_elem &&
@@ -11343,11 +11344,11 @@ record_func_map(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
1134311344
}
1134411345

1134511346
if (!aux->map_ptr_state.map_ptr)
11346-
bpf_map_ptr_store(aux, meta->map_ptr,
11347-
!meta->map_ptr->bypass_spec_v1, false);
11348-
else if (aux->map_ptr_state.map_ptr != meta->map_ptr)
11349-
bpf_map_ptr_store(aux, meta->map_ptr,
11350-
!meta->map_ptr->bypass_spec_v1, true);
11347+
bpf_map_ptr_store(aux, meta->map.ptr,
11348+
!meta->map.ptr->bypass_spec_v1, false);
11349+
else if (aux->map_ptr_state.map_ptr != meta->map.ptr)
11350+
bpf_map_ptr_store(aux, meta->map.ptr,
11351+
!meta->map.ptr->bypass_spec_v1, true);
1135111352
return 0;
1135211353
}
1135311354

@@ -11357,7 +11358,7 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
1135711358
{
1135811359
struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
1135911360
struct bpf_reg_state *reg;
11360-
struct bpf_map *map = meta->map_ptr;
11361+
struct bpf_map *map = meta->map.ptr;
1136111362
u64 val, max;
1136211363
int err;
1136311364

@@ -11913,22 +11914,22 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
1191311914
* can check 'value_size' boundary of memory access
1191411915
* to map element returned from bpf_map_lookup_elem()
1191511916
*/
11916-
if (meta.map_ptr == NULL) {
11917+
if (meta.map.ptr == NULL) {
1191711918
verifier_bug(env, "unexpected null map_ptr");
1191811919
return -EFAULT;
1191911920
}
1192011921

1192111922
if (func_id == BPF_FUNC_map_lookup_elem &&
11922-
can_elide_value_nullness(meta.map_ptr->map_type) &&
11923+
can_elide_value_nullness(meta.map.ptr->map_type) &&
1192311924
meta.const_map_key >= 0 &&
11924-
meta.const_map_key < meta.map_ptr->max_entries)
11925+
meta.const_map_key < meta.map.ptr->max_entries)
1192511926
ret_flag &= ~PTR_MAYBE_NULL;
1192611927

11927-
regs[BPF_REG_0].map_ptr = meta.map_ptr;
11928-
regs[BPF_REG_0].map_uid = meta.map_uid;
11928+
regs[BPF_REG_0].map_ptr = meta.map.ptr;
11929+
regs[BPF_REG_0].map_uid = meta.map.uid;
1192911930
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE | ret_flag;
1193011931
if (!type_may_be_null(ret_flag) &&
11931-
btf_record_has_field(meta.map_ptr->record, BPF_SPIN_LOCK | BPF_RES_SPIN_LOCK)) {
11932+
btf_record_has_field(meta.map.ptr->record, BPF_SPIN_LOCK | BPF_RES_SPIN_LOCK)) {
1193211933
regs[BPF_REG_0].id = ++env->id_gen;
1193311934
}
1193411935
break;
@@ -12031,7 +12032,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
1203112032
if (type_may_be_null(regs[BPF_REG_0].type))
1203212033
regs[BPF_REG_0].id = ++env->id_gen;
1203312034

12034-
if (helper_multiple_ref_obj_use(func_id, meta.map_ptr)) {
12035+
if (helper_multiple_ref_obj_use(func_id, meta.map.ptr)) {
1203512036
verifier_bug(env, "func %s#%d sets ref_obj_id more than once",
1203612037
func_id_name(func_id), func_id);
1203712038
return -EFAULT;
@@ -12043,7 +12044,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
1204312044
if (is_ptr_cast_function(func_id) || is_dynptr_ref_function(func_id)) {
1204412045
/* For release_reference() */
1204512046
regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id;
12046-
} else if (is_acquire_function(func_id, meta.map_ptr)) {
12047+
} else if (is_acquire_function(func_id, meta.map.ptr)) {
1204712048
int id = acquire_reference(env, insn_idx);
1204812049

1204912050
if (id < 0)
@@ -12058,7 +12059,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
1205812059
if (err)
1205912060
return err;
1206012061

12061-
err = check_map_func_compatibility(env, meta.map_ptr, func_id);
12062+
err = check_map_func_compatibility(env, meta.map.ptr, func_id);
1206212063
if (err)
1206312064
return err;
1206412065

0 commit comments

Comments
 (0)