* [PATCH bpf-next v2 0/2] Fix unaligned enum values in btf_dump
@ 2026-11-15 8:49 Hungyu Lin
2026-11-15 8:49 ` [PATCH bpf-next v2 1/2] libbpf: Fix sign extension of unaligned enums in btf_dump_get_enum_value() Hungyu Lin
2026-11-15 8:49 ` [PATCH bpf-next v2 2/2] selftests/bpf: Dump unaligned enums and a zeroed fs_context Hungyu Lin
0 siblings, 2 replies; 4+ messages in thread
From: Hungyu Lin @ 2026-11-15 8:49 UTC (permalink / raw)
To: andrii, bpf
Cc: ast, daniel, eddyz87, memxor, martin.lau, song, yonghong.song,
jolsa, emil, ihor.solodrai, alan.maguire, shuah, alexis.lothore,
luisflavieira, ameryhung, linux-kselftest, linux-kernel,
dennylin0707
btf_dump_get_enum_value() reads unaligned enum values through
btf_dump_get_bitfield_value() with a zero bit size, which shifts a
__u64 by 64. Patch 1 copies unaligned enum data into an aligned buffer
instead, as btf_dump_int_data() does. Patch 2 adds the tests Alexei
posted in the v1 review.
Changes in v2:
- Describe the undefined shift in the commit log.
- Drop the data_end check, which broke the dump of struct fs_context
without emit_zeroes.
- Add the selftests from the v1 review.
v1: https://lore.kernel.org/bpf/20261113223449.97604-1-dennylin0707@gmail.com/
Hungyu Lin (2):
libbpf: Fix sign extension of unaligned enums in
btf_dump_get_enum_value()
selftests/bpf: Dump unaligned enums and a zeroed fs_context
tools/lib/bpf/btf_dump.c | 13 ++++---------
tools/testing/selftests/bpf/prog_tests/btf_dump.c | 10 +++++++++-
2 files changed, 13 insertions(+), 10 deletions(-)
base-commit: 0021f17128de5dc0b19f1a523f448df2440d8088
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH bpf-next v2 1/2] libbpf: Fix sign extension of unaligned enums in btf_dump_get_enum_value() 2026-11-15 8:49 [PATCH bpf-next v2 0/2] Fix unaligned enum values in btf_dump Hungyu Lin @ 2026-11-15 8:49 ` Hungyu Lin 2026-11-15 8:49 ` [PATCH bpf-next v2 2/2] selftests/bpf: Dump unaligned enums and a zeroed fs_context Hungyu Lin 1 sibling, 0 replies; 4+ messages in thread From: Hungyu Lin @ 2026-11-15 8:49 UTC (permalink / raw) To: andrii, bpf Cc: ast, daniel, eddyz87, memxor, martin.lau, song, yonghong.song, jolsa, emil, ihor.solodrai, alan.maguire, shuah, alexis.lothore, luisflavieira, ameryhung, linux-kselftest, linux-kernel, dennylin0707 btf_dump_get_enum_value() reads unaligned enum values through btf_dump_get_bitfield_value() with a zero bit size. That makes right_shift_bits 64 in *value = (num << left_shift_bits) >> right_shift_bits; which is undefined behavior for a __u64 on both endians. The path also bypasses the signed loads used for aligned data, so a negative value of a signed enum can lose its enumerator name when the data is unaligned. Fix this by copying unaligned enum data into an aligned buffer, as btf_dump_int_data() does, and reading it with the same loads as aligned data. Fixes: 920d16af9b42 ("libbpf: BTF dumper support for typed data") Signed-off-by: Hungyu Lin <dennylin0707@gmail.com> --- tools/lib/bpf/btf_dump.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index bbe86928b3ec..a80762a70cd0 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -2329,16 +2329,11 @@ static int btf_dump_get_enum_value(struct btf_dump *d, __s64 *value) { bool is_signed = btf_kflag(t); + char buf[8] __attribute__((aligned(8))); - if (!ptr_is_aligned(d->btf, id, data)) { - __u64 val; - int err; - - err = btf_dump_get_bitfield_value(d, t, data, 0, 0, &val); - if (err) - return err; - *value = (__s64)val; - return 0; + if (t->size <= sizeof(buf) && !ptr_is_aligned(d->btf, id, data)) { + memcpy(buf, data, t->size); + data = buf; } switch (t->size) { -- 2.43.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH bpf-next v2 2/2] selftests/bpf: Dump unaligned enums and a zeroed fs_context 2026-11-15 8:49 [PATCH bpf-next v2 0/2] Fix unaligned enum values in btf_dump Hungyu Lin 2026-11-15 8:49 ` [PATCH bpf-next v2 1/2] libbpf: Fix sign extension of unaligned enums in btf_dump_get_enum_value() Hungyu Lin @ 2026-11-15 8:49 ` Hungyu Lin 2026-11-15 9:09 ` sashiko-bot 1 sibling, 1 reply; 4+ messages in thread From: Hungyu Lin @ 2026-11-15 8:49 UTC (permalink / raw) To: andrii, bpf Cc: ast, daniel, eddyz87, memxor, martin.lau, song, yonghong.song, jolsa, emil, ihor.solodrai, alan.maguire, shuah, alexis.lothore, luisflavieira, ameryhung, linux-kselftest, linux-kernel, dennylin0707 Dump the signed enum value from an unaligned address in the enum data test. Also dump a zeroed struct fs_context without emit_zeroes in the struct data test, which covers phase, an enum bitfield 3 bytes before the end of the struct. Suggested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Hungyu Lin <dennylin0707@gmail.com> --- tools/testing/selftests/bpf/prog_tests/btf_dump.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/btf_dump.c b/tools/testing/selftests/bpf/prog_tests/btf_dump.c index b5c90f729339..d6fd9933ff25 100644 --- a/tools/testing/selftests/bpf/prog_tests/btf_dump.c +++ b/tools/testing/selftests/bpf/prog_tests/btf_dump.c @@ -945,7 +945,7 @@ static void test_btf_dump_enum_data(struct btf *btf, struct btf_dump *d, char *str) { __u32 high = 0x80000000; - __s32 neg = -1; + __s32 neg[2] = { -1, -1 }; /* enum where enum value does (and does not) exist */ TEST_BTF_DUMP_DATA_C(btf, d, "enum", str, enum bpf_cmd, BTF_F_COMPACT, @@ -994,6 +994,8 @@ static void test_btf_dump_enum_data(struct btf *btf, struct btf_dump *d, "(enum test_enum_u32)TEST_ENUM_HIGH"), "dump unsigned enum"); ASSERT_OK(btf_dump_data(btf, d, "test_enum_s32", NULL, 0, &neg, 4, str, "(enum test_enum_s32)TEST_ENUM_NEG"), "dump signed enum"); + ASSERT_OK(btf_dump_data(btf, d, "test_enum_s32", NULL, 0, (void *)neg + 1, 4, str, + "(enum test_enum_s32)TEST_ENUM_NEG"), "dump unaligned enum"); btf_dump__free(d); } @@ -1182,6 +1184,12 @@ static void test_btf_dump_struct_data(struct btf *btf, struct btf_dump *d, type_sz = btf__resolve_size(btf, type_id); str[0] = '\0'; + /* 'phase' is an enum bitfield 3 bytes before the end */ + ret = btf_dump__dump_type_data(d, type_id, zero_data, type_sz, &opts); + ASSERT_EQ(ret, type_sz, + "unexpected return value dumping zeroed fs_context"); + + str[0] = '\0'; opts.emit_zeroes = true; ret = btf_dump__dump_type_data(d, type_id, zero_data, type_sz, &opts); ASSERT_EQ(ret, type_sz, -- 2.43.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Dump unaligned enums and a zeroed fs_context 2026-11-15 8:49 ` [PATCH bpf-next v2 2/2] selftests/bpf: Dump unaligned enums and a zeroed fs_context Hungyu Lin @ 2026-11-15 9:09 ` sashiko-bot 0 siblings, 0 replies; 4+ messages in thread From: sashiko-bot @ 2026-11-15 9:09 UTC (permalink / raw) To: Hungyu Lin, bpf Thank you for your contribution! Sashiko AI review found 1 potential issue to consider: - [Medium] selftests/bpf: enum bitfield OOB read in btf_dump_type_data_check_zero() -- commit 796295518e9df1f4059137fab9435ca1e6bd6793 Author: Hungyu Lin <dennylin0707@gmail.com> selftests/bpf: Dump unaligned enums and a zeroed fs_context This commit extends the BTF data dump selftests to dump a signed enum from an unaligned address and a zeroed struct fs_context without emit_zeroes. > diff --git a/tools/testing/selftests/bpf/prog_tests/btf_dump.c b/tools/testing/selftests/bpf/prog_tests/btf_dump.c > index b5c90f7293398..d6fd9933ff258 100644 > --- a/tools/testing/selftests/bpf/prog_tests/btf_dump.c > +++ b/tools/testing/selftests/bpf/prog_tests/btf_dump.c [ ... ] > @@ -1182,6 +1184,12 @@ static void test_btf_dump_struct_data(struct btf *btf, struct btf_dump *d, > type_sz = btf__resolve_size(btf, type_id); > str[0] = '\0'; > > + /* 'phase' is an enum bitfield 3 bytes before the end */ > + ret = btf_dump__dump_type_data(d, type_id, zero_data, type_sz, &opts); > + ASSERT_EQ(ret, type_sz, > + "unexpected return value dumping zeroed fs_context"); [Severity: Medium] Does dumping struct fs_context with emit_zeroes set to false read 1 byte past zero_data + type_sz when checking the phase enum bitfield? In struct fs_context, phase is an 8-bit enum bitfield (t->size == 4) placed 3 bytes before the end of the struct. btf_dump_type_data_check_overflow() checks bit_sz (1 byte) and allows the access, but btf_dump_type_data_check_zero() ignores bit_sz for BTF_KIND_ENUM and BTF_KIND_ENUM64 and reads the full t->size via btf_dump_get_enum_value(): tools/lib/bpf/btf_dump.c:btf_dump_type_data_check_zero() { ... case BTF_KIND_INT: if (bit_sz) return btf_dump_bitfield_check_zero(d, t, data, bits_offset, bit_sz); return btf_dump_base_type_check_zero(d, t, id, data); ... case BTF_KIND_ENUM: case BTF_KIND_ENUM64: err = btf_dump_get_enum_value(d, t, data, id, &value); ... } Because data at type_sz - 3 is unaligned for a 4-byte enum, btf_dump_get_enum_value() copies 4 bytes with memcpy(buf, data, t->size), reading 1 byte past d->typed_dump->data_end and mixing adjacent bitfields and out-of-bounds memory into the zero check. In this test, passing the oversized 512-byte zero_data buffer and only asserting ret == type_sz hides the out-of-bounds read from AddressSanitizer. Should btf_dump_type_data_check_zero() call btf_dump_bitfield_check_zero() when bit_sz is non-zero for BTF_KIND_ENUM and BTF_KIND_ENUM64, matching BTF_KIND_INT and btf_dump_dump_type_data()? -- Sashiko AI review · https://sashiko.dev/#/patchset/20261115084923.53182-1-dennylin0707@gmail.com?part=2 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-15 9:09 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-15 8:49 [PATCH bpf-next v2 0/2] Fix unaligned enum values in btf_dump Hungyu Lin 2026-11-15 8:49 ` [PATCH bpf-next v2 1/2] libbpf: Fix sign extension of unaligned enums in btf_dump_get_enum_value() Hungyu Lin 2026-11-15 8:49 ` [PATCH bpf-next v2 2/2] selftests/bpf: Dump unaligned enums and a zeroed fs_context Hungyu Lin 2026-11-15 9:09 ` sashiko-bot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.