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

Showing the changes to kernel (1 of 1 file). Show all

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
20162 if (ret < 0)20162 if (ret < 0)
20163 goto skip_full_check;20163 goto skip_full_check;
20164 20164
20165 /* Collect the kfunc descriptors used during verification. */
20166 ret = add_kfuncs(env);
20167 if (ret < 0)
20168 goto skip_full_check;
20169
20170 ret = check_subprogs(env);20165 ret = check_subprogs(env);
20171 if (ret < 0)20166 if (ret < 0)
20172 goto skip_full_check;20167 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
20176 if (ret < 0)20171 if (ret < 0)
20177 goto skip_full_check;20172 goto skip_full_check;
20178 20173
20174 /* Validate instructions and resolve the program's referenced resources. */
20179 ret = check_and_resolve_insns(env);20175 ret = check_and_resolve_insns(env);
20180 if (ret < 0)20176 if (ret < 0)
20181 goto skip_full_check;20177 goto skip_full_check;
20182 20178
20179 /* Build kfunc prototypes after resolving program resources. */
20180 ret = add_kfuncs(env);
20181 if (ret < 0)
20182 goto skip_full_check;
20183
20183 if (bpf_prog_is_offloaded(env->prog->aux)) {20184 if (bpf_prog_is_offloaded(env->prog->aux)) {
20184 ret = bpf_prog_offload_verifier_prep(env->prog);20185 ret = bpf_prog_offload_verifier_prep(env->prog);
20185 if (ret)20186 if (ret)