On 5/21/24 11:12, Eduard Zingerman wrote:
On Mon, 2024-05-20 at 13:40 -0700, Kui-Feng Lee wrote:
The verifier has field information for specific special types, such as
kptr, rbtree root, and list head. These types are handled
differently. However, we did not previously examine the types of fields of
a struct type variable. Field information records were not generated for
the kptrs, rbtree roots, and linked_list heads that are not located at the
outermost struct type of a variable.
For example,
struct A {
struct task_struct __kptr * task;
};
struct B {
struct A mem_a;
}
struct B var_b;
It did not examine "struct A" so as not to generate field information for
the kptr in "struct A" for "var_b".
This patch enables BPF programs to define fields of these special types in
a struct type other than the direct type of a variable or in a struct type
that is the type of a field in the value type of a map.
Signed-off-by: Kui-Feng Lee <thinker.li@xxxxxxxxx>
---
Acked-by: Eduard Zingerman <eddyz87@xxxxxxxxx>
[...]
+ /* Look into variables of struct types */
+ if ((field_type == BPF_KPTR_REF || !field_type) &&
+ __btf_type_is_struct(var_type)) {
This code would have looked nicer (handled inside the same switch as
all other branches) if we had BPF_NESTED_FIELD in `btf_field_type` or
something like that. But that's probably be an overkill.
After thinking twice, I will change btf_get_field_type() to return
BPF_KPTR_REF only if the type is not struct.
+ sz = var_type->size;
+ if (expected_size && expected_size != sz * nelems)
+ return 0;
+ ret = btf_find_nested_struct(btf, var_type, off, nelems, field_mask,
+ &info[0], info_cnt);
+ return ret;
+ }
[...]