Message ID | 20220909092107.3035-1-oss@lmb.io (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | BPF |
Headers | show |
Series | [bpf] bpf: btf: fix truncated last_member_type_id in btf_struct_resolve | expand |
On 09/09, Lorenz Bauer wrote: > When trying to finish resolving a struct member, btf_struct_resolve > saves the member type id in a u16 temporary variable. This truncates > the 32 bit type id value if it exceeds UINT16_MAX. > As a result, structs that have members with type ids > UINT16_MAX and > which need resolution will fail with a message like this: > [67414] STRUCT ff_device size=120 vlen=12 > effect_owners type_id=67434 bits_offset=960 Member exceeds > struct_size > Fix this by changing the type of last_member_type_id to u32. Makes sense to me; I'm surprised the compiler isn't raising a warning on line: last_member_type_id = last_member->type; Reviewed-by: Stanislav Fomichev <sdf@google.com> > Fixes: eb3f595dab40 ("bpf: btf: Validate type reference") > Signed-off-by: Lorenz Bauer <oss@lmb.io> > --- > kernel/bpf/btf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index 7e64447659f3..36fd4b509294 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c > @@ -3128,7 +3128,7 @@ static int btf_struct_resolve(struct > btf_verifier_env *env, > if (v->next_member) { > const struct btf_type *last_member_type; > const struct btf_member *last_member; > - u16 last_member_type_id; > + u32 last_member_type_id; > last_member = btf_type_member(v->t) + v->next_member - 1; > last_member_type_id = last_member->type; > -- > 2.34.1
On 9/9/22 2:21 AM, Lorenz Bauer wrote: > When trying to finish resolving a struct member, btf_struct_resolve > saves the member type id in a u16 temporary variable. This truncates > the 32 bit type id value if it exceeds UINT16_MAX. > > As a result, structs that have members with type ids > UINT16_MAX and > which need resolution will fail with a message like this: > > [67414] STRUCT ff_device size=120 vlen=12 > effect_owners type_id=67434 bits_offset=960 Member exceeds struct_size > > Fix this by changing the type of last_member_type_id to u32. > > Fixes: eb3f595dab40 ("bpf: btf: Validate type reference") The fix tag should be Fixes: a0791f0df7d2 ("bpf: fix BTF limits") > Signed-off-by: Lorenz Bauer <oss@lmb.io> > --- > kernel/bpf/btf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index 7e64447659f3..36fd4b509294 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c > @@ -3128,7 +3128,7 @@ static int btf_struct_resolve(struct btf_verifier_env *env, > if (v->next_member) { > const struct btf_type *last_member_type; > const struct btf_member *last_member; > - u16 last_member_type_id; > + u32 last_member_type_id; The change makes sense. The kernel's vmlinux and module btf parsing doesn't go through this resolve check though. Are you trying to __sys_bpf(BPF_BTF_LOAD) the btf from the vmlinux file into the kernel ?
On Fri, 9 Sep 2022, at 19:17, Martin KaFai Lau wrote: > > The fix tag should be > > Fixes: a0791f0df7d2 ("bpf: fix BTF limits") Ah, thanks very much! Sent a v2. > The change makes sense. > > The kernel's vmlinux and module btf parsing doesn't go through this > resolve check though. Are you trying to __sys_bpf(BPF_BTF_LOAD) the btf > from the vmlinux file into the kernel ? Yes, with the twist that the BTF was serialised by github.com/cilium/ebpf instead of libbpf.
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 7e64447659f3..36fd4b509294 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -3128,7 +3128,7 @@ static int btf_struct_resolve(struct btf_verifier_env *env, if (v->next_member) { const struct btf_type *last_member_type; const struct btf_member *last_member; - u16 last_member_type_id; + u32 last_member_type_id; last_member = btf_type_member(v->t) + v->next_member - 1; last_member_type_id = last_member->type;
When trying to finish resolving a struct member, btf_struct_resolve saves the member type id in a u16 temporary variable. This truncates the 32 bit type id value if it exceeds UINT16_MAX. As a result, structs that have members with type ids > UINT16_MAX and which need resolution will fail with a message like this: [67414] STRUCT ff_device size=120 vlen=12 effect_owners type_id=67434 bits_offset=960 Member exceeds struct_size Fix this by changing the type of last_member_type_id to u32. Fixes: eb3f595dab40 ("bpf: btf: Validate type reference") Signed-off-by: Lorenz Bauer <oss@lmb.io> --- kernel/bpf/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)