diff mbox series

[bpf-next,v1] libbpf: ensure new BTF objects inherit input endianness

Message ID 20240830095150.278881-1-tony.ambardar@gmail.com (mailing list archive)
State Accepted
Delegated to: BPF
Headers show
Series [bpf-next,v1] libbpf: ensure new BTF objects inherit input endianness | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-18 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-21 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
netdev/tree_selection success Clearly marked for bpf-next
netdev/apply fail Patch does not apply to bpf-next-0

Commit Message

Tony Ambardar Aug. 30, 2024, 9:51 a.m. UTC
The pahole master branch recently added support for "distilled BTF" based
on libbpf v1.5, but may add .BTF and .BTF.base sections with the wrong byte
order (e.g. on s390x BPF CI), which then lead to kernel Oops when loaded.

Fix by updating libbpf's btf__distill_base() and btf_new_empty() to retain
the byte order of any source BTF objects when creating new ones.

Reported-by: Song Liu <song@kernel.org>
Reported-by: Eduard Zingerman <eddyz87@gmail.com>
Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/6358db36c5f68b07873a0a5be2d062b1af5ea5f8.camel@gmail.com/
Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
---
 tools/lib/bpf/btf.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Eduard Zingerman Aug. 30, 2024, 11:15 a.m. UTC | #1
On Fri, 2024-08-30 at 02:51 -0700, Tony Ambardar wrote:
> The pahole master branch recently added support for "distilled BTF" based
> on libbpf v1.5, but may add .BTF and .BTF.base sections with the wrong byte
> order (e.g. on s390x BPF CI), which then lead to kernel Oops when loaded.
> 
> Fix by updating libbpf's btf__distill_base() and btf_new_empty() to retain
> the byte order of any source BTF objects when creating new ones.
> 
> Reported-by: Song Liu <song@kernel.org>
> Reported-by: Eduard Zingerman <eddyz87@gmail.com>
> Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
> Link: https://lore.kernel.org/bpf/6358db36c5f68b07873a0a5be2d062b1af5ea5f8.camel@gmail.com/
> Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
> ---

Acked-by: Eduard Zingerman <eddyz87@gmail.com>

But we also need a test for this. Like the one attached.
Or Alan can share his test, which is much shorter but skips round trip to bytes and back.

[...]
Alan Maguire Aug. 30, 2024, 11:25 a.m. UTC | #2
On 30/08/2024 12:15, Eduard Zingerman wrote:
> On Fri, 2024-08-30 at 02:51 -0700, Tony Ambardar wrote:
>> The pahole master branch recently added support for "distilled BTF" based
>> on libbpf v1.5, but may add .BTF and .BTF.base sections with the wrong byte
>> order (e.g. on s390x BPF CI), which then lead to kernel Oops when loaded.
>>
>> Fix by updating libbpf's btf__distill_base() and btf_new_empty() to retain
>> the byte order of any source BTF objects when creating new ones.
>>
>> Reported-by: Song Liu <song@kernel.org>
>> Reported-by: Eduard Zingerman <eddyz87@gmail.com>
>> Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
>> Link: https://lore.kernel.org/bpf/6358db36c5f68b07873a0a5be2d062b1af5ea5f8.camel@gmail.com/
>> Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
>> ---
> 
> Acked-by: Eduard Zingerman <eddyz87@gmail.com>
>

Tested-by: Alan Maguire <alan.maguire@oracle.com>

Thanks for the fix!

> But we also need a test for this. Like the one attached.
> Or Alan can share his test, which is much shorter but skips round trip to bytes and back.
>

Eduard's test is better than mine; mine was a simple addition to
btf_endian() tests that checked split/distilled BTF matched endianness
of the originating BTF for non-native endianness. Having actual
non-native endianness _use_ as in Eduard's test is much preferred I think.

> [...]
Andrii Nakryiko Aug. 30, 2024, 3:58 p.m. UTC | #3
On Fri, Aug 30, 2024 at 4:26 AM Alan Maguire <alan.maguire@oracle.com> wrote:
>
> On 30/08/2024 12:15, Eduard Zingerman wrote:
> > On Fri, 2024-08-30 at 02:51 -0700, Tony Ambardar wrote:
> >> The pahole master branch recently added support for "distilled BTF" based
> >> on libbpf v1.5, but may add .BTF and .BTF.base sections with the wrong byte
> >> order (e.g. on s390x BPF CI), which then lead to kernel Oops when loaded.
> >>
> >> Fix by updating libbpf's btf__distill_base() and btf_new_empty() to retain
> >> the byte order of any source BTF objects when creating new ones.
> >>
> >> Reported-by: Song Liu <song@kernel.org>
> >> Reported-by: Eduard Zingerman <eddyz87@gmail.com>
> >> Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
> >> Link: https://lore.kernel.org/bpf/6358db36c5f68b07873a0a5be2d062b1af5ea5f8.camel@gmail.com/
> >> Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
> >> ---
> >
> > Acked-by: Eduard Zingerman <eddyz87@gmail.com>
> >
>
> Tested-by: Alan Maguire <alan.maguire@oracle.com>
>
> Thanks for the fix!
>
> > But we also need a test for this. Like the one attached.
> > Or Alan can share his test, which is much shorter but skips round trip to bytes and back.
> >
>
> Eduard's test is better than mine; mine was a simple addition to
> btf_endian() tests that checked split/distilled BTF matched endianness
> of the originating BTF for non-native endianness. Having actual
> non-native endianness _use_ as in Eduard's test is much preferred I think.

Eduard, please send it as a proper patch?

>
> > [...]
Andrii Nakryiko Aug. 30, 2024, 4 p.m. UTC | #4
On Fri, Aug 30, 2024 at 2:52 AM Tony Ambardar <tony.ambardar@gmail.com> wrote:
>
> The pahole master branch recently added support for "distilled BTF" based
> on libbpf v1.5, but may add .BTF and .BTF.base sections with the wrong byte

there is no libbpf v1.5 release, are we talking about using unreleased
master branch?

> order (e.g. on s390x BPF CI), which then lead to kernel Oops when loaded.
>
> Fix by updating libbpf's btf__distill_base() and btf_new_empty() to retain
> the byte order of any source BTF objects when creating new ones.
>
> Reported-by: Song Liu <song@kernel.org>
> Reported-by: Eduard Zingerman <eddyz87@gmail.com>
> Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
> Link: https://lore.kernel.org/bpf/6358db36c5f68b07873a0a5be2d062b1af5ea5f8.camel@gmail.com/
> Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
> ---
>  tools/lib/bpf/btf.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
> index 064cfe126c09..7726b7c6d40a 100644
> --- a/tools/lib/bpf/btf.c
> +++ b/tools/lib/bpf/btf.c
> @@ -996,6 +996,7 @@ static struct btf *btf_new_empty(struct btf *base_btf)
>                 btf->base_btf = base_btf;
>                 btf->start_id = btf__type_cnt(base_btf);
>                 btf->start_str_off = base_btf->hdr->str_len;
> +               btf->swapped_endian = base_btf->swapped_endian;
>         }
>
>         /* +1 for empty string at offset 0 */
> @@ -5554,6 +5555,10 @@ int btf__distill_base(const struct btf *src_btf, struct btf **new_base_btf,
>         new_base = btf__new_empty();
>         if (!new_base)
>                 return libbpf_err(-ENOMEM);
> +       err = btf__set_endianness(new_base, btf__endianness(src_btf));
> +       if (err < 0)
> +               goto done;

This error check is really unnecessary and paranoid, because the only
way btf__set_endianness() can fail is if the provided endianness enum
is corrupted (some invalid int cast to enum). But in this case we are
getting it from libbpf itself, which will always be correct. So I
think I'll drop the error check while applying.

> +
>         dist.id_map = calloc(n, sizeof(*dist.id_map));
>         if (!dist.id_map) {
>                 err = -ENOMEM;
> --
> 2.34.1
>
Andrii Nakryiko Aug. 30, 2024, 5:51 p.m. UTC | #5
On Fri, Aug 30, 2024 at 9:00 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Fri, Aug 30, 2024 at 2:52 AM Tony Ambardar <tony.ambardar@gmail.com> wrote:
> >
> > The pahole master branch recently added support for "distilled BTF" based
> > on libbpf v1.5, but may add .BTF and .BTF.base sections with the wrong byte
>
> there is no libbpf v1.5 release, are we talking about using unreleased
> master branch?
>
> > order (e.g. on s390x BPF CI), which then lead to kernel Oops when loaded.
> >
> > Fix by updating libbpf's btf__distill_base() and btf_new_empty() to retain
> > the byte order of any source BTF objects when creating new ones.
> >
> > Reported-by: Song Liu <song@kernel.org>
> > Reported-by: Eduard Zingerman <eddyz87@gmail.com>
> > Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
> > Link: https://lore.kernel.org/bpf/6358db36c5f68b07873a0a5be2d062b1af5ea5f8.camel@gmail.com/
> > Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
> > ---
> >  tools/lib/bpf/btf.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >

Also added

Fixes: ba451366bf44 ("libbpf: Implement basic split BTF support")
Fixes: 58e185a0dc35 ("libbpf: Add btf__distill_base() creating split
BTF with distilled base BTF")

> > diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
> > index 064cfe126c09..7726b7c6d40a 100644
> > --- a/tools/lib/bpf/btf.c
> > +++ b/tools/lib/bpf/btf.c
> > @@ -996,6 +996,7 @@ static struct btf *btf_new_empty(struct btf *base_btf)
> >                 btf->base_btf = base_btf;
> >                 btf->start_id = btf__type_cnt(base_btf);
> >                 btf->start_str_off = base_btf->hdr->str_len;
> > +               btf->swapped_endian = base_btf->swapped_endian;
> >         }
> >
> >         /* +1 for empty string at offset 0 */
> > @@ -5554,6 +5555,10 @@ int btf__distill_base(const struct btf *src_btf, struct btf **new_base_btf,
> >         new_base = btf__new_empty();
> >         if (!new_base)
> >                 return libbpf_err(-ENOMEM);
> > +       err = btf__set_endianness(new_base, btf__endianness(src_btf));
> > +       if (err < 0)
> > +               goto done;
>
> This error check is really unnecessary and paranoid, because the only
> way btf__set_endianness() can fail is if the provided endianness enum
> is corrupted (some invalid int cast to enum). But in this case we are
> getting it from libbpf itself, which will always be correct. So I
> think I'll drop the error check while applying.
>
> > +
> >         dist.id_map = calloc(n, sizeof(*dist.id_map));
> >         if (!dist.id_map) {
> >                 err = -ENOMEM;
> > --
> > 2.34.1
> >
diff mbox series

Patch

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 064cfe126c09..7726b7c6d40a 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -996,6 +996,7 @@  static struct btf *btf_new_empty(struct btf *base_btf)
 		btf->base_btf = base_btf;
 		btf->start_id = btf__type_cnt(base_btf);
 		btf->start_str_off = base_btf->hdr->str_len;
+		btf->swapped_endian = base_btf->swapped_endian;
 	}
 
 	/* +1 for empty string at offset 0 */
@@ -5554,6 +5555,10 @@  int btf__distill_base(const struct btf *src_btf, struct btf **new_base_btf,
 	new_base = btf__new_empty();
 	if (!new_base)
 		return libbpf_err(-ENOMEM);
+	err = btf__set_endianness(new_base, btf__endianness(src_btf));
+	if (err < 0)
+		goto done;
+
 	dist.id_map = calloc(n, sizeof(*dist.id_map));
 	if (!dist.id_map) {
 		err = -ENOMEM;