History

bpf: Collect kfuncs after resolving program resources

The kfunc descriptors include argument prototypes generated while calls are collected. Some argument classifications need program auxiliary state derived from referenced maps, such as the arena associated with the program. This avoids a footgun in get_kfunc_arg_type() checks where we do validation on whether program has prog->aux->arena and it hasn't been resolved yet. check_and_resolve_insns() records used maps and populates that state. It must remain after bpf_check_btf_info(), which applies kernel-side CO-RE relocations, so that instruction validation and the program tag observe the relocated instruction stream. Move only add_kfuncs() after instruction and resource resolution. Subprogram discovery and validation remain before the full BTF phase because that phase needs the complete subprogram layout. Add a short comment describing the resource resolution phase at the call site.

Kumar Kartikeya Dwivedi committed 3 months ago

Commit d98b2d41 parent 41f36ff1 file · +6 −5Browse files

Unified · Split

kernel/bpf/verifier.c+6−5
@@ -20162,11 +20162,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, · 20161 unmodified lines
2016220162 if (ret < 0)
2016320163 goto skip_full_check;
2016420164
20165− /* Collect the kfunc descriptors used during verification. */
20166− ret = add_kfuncs(env);
20167− if (ret < 0)
20168− goto skip_full_check;
20169−
2017020165 ret = check_subprogs(env);
2017120166 if (ret < 0)
2017220167 goto skip_full_check;
@@ -20176,10 +20171,16 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, · 3 unmodified lines
2017620171 if (ret < 0)
2017720172 goto skip_full_check;
2017820173
20174+ /* Validate instructions and resolve the program's referenced resources. */
2017920175 ret = check_and_resolve_insns(env);
2018020176 if (ret < 0)
2018120177 goto skip_full_check;
2018220178
20179+ /* Build kfunc prototypes after resolving program resources. */
20180+ ret = add_kfuncs(env);
20181+ if (ret < 0)
20182+ goto skip_full_check;
20183+
2018320184 if (bpf_prog_is_offloaded(env->prog->aux)) {
2018420185 ret = bpf_prog_offload_verifier_prep(env->prog);
2018520186 if (ret)