* [PATCH bpf-next v3 1/3] bpf: Check tail zero of bpf_map_info
2026-06-05 15:52 [PATCH bpf-next v3 0/3] bpf: Check tail zero of bpf_map_info and bpf_prog_info Leon Hwang
@ 2026-06-05 15:52 ` Leon Hwang
2026-06-05 15:52 ` [PATCH bpf-next v3 2/3] bpf: Check tail zero of bpf_prog_info Leon Hwang
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Leon Hwang @ 2026-06-05 15:52 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
Shuah Khan, Yuyang Huang, Leon Hwang, KP Singh, Dave Marchevsky,
Stanislav Fomichev, linux-kernel, linux-kselftest,
kernel-patches-bot, Mykyta Yatsenko
Since there're 4 bytes padding at the end of struct bpf_map_info, they
won't be checked by bpf_check_uarg_tail_zero().
pahole -C bpf_map_info ./vmlinux
struct bpf_map_info {
...
__u64 hash __attribute__((__aligned__(8))); /* 88 8 */
__u32 hash_size; /* 96 4 */
/* size: 104, cachelines: 2, members: 18 */
/* padding: 4 */
/* forced alignments: 1 */
/* last cacheline: 40 bytes */
} __attribute__((__aligned__(8)));
If a future kernel extension adds a new 4-byte field, older userspace
programs allocating this structure on the stack might inadvertently pass
uninitialized stack garbage into the new field, permanently breaking
backward compatibility. -- sashiko [1]
Fix it by changing sizeof(info) to
offsetofend(struct bpf_map_info, hash_size).
And, add "__u32 :32" to the tail of struct bpf_map_info.
[1] https://lore.kernel.org/bpf/20260513224823.6494FC19425@smtp.kernel.org/
Fixes: ea2e6467ac36 ("bpf: Return hashes of maps in BPF_OBJ_GET_INFO_BY_FD")
Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/uapi/linux/bpf.h | 1 +
kernel/bpf/syscall.c | 5 +++--
tools/include/uapi/linux/bpf.h | 1 +
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index bed9b1b4d5ef..e1730f449d9e 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -6733,6 +6733,7 @@ struct bpf_map_info {
__u64 map_extra;
__aligned_u64 hash;
__u32 hash_size;
+ __u32 :32;
} __attribute__((aligned(8)));
struct bpf_btf_info {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 31a3b70a0b5d..89f020a44fc9 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5406,10 +5406,11 @@ static int bpf_map_get_info_by_fd(struct file *file,
{
struct bpf_map_info __user *uinfo = u64_to_user_ptr(attr->info.info);
struct bpf_map_info info;
- u32 info_len = attr->info.info_len;
+ u32 info_len = attr->info.info_len, len;
int err;
- err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), sizeof(info), info_len);
+ len = offsetofend(struct bpf_map_info, hash_size);
+ err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), len, info_len);
if (err)
return err;
info_len = min_t(u32, sizeof(info), info_len);
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 7d0b282ba674..7caf667e86fe 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -6733,6 +6733,7 @@ struct bpf_map_info {
__u64 map_extra;
__aligned_u64 hash;
__u32 hash_size;
+ __u32 :32;
} __attribute__((aligned(8)));
struct bpf_btf_info {
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH bpf-next v3 2/3] bpf: Check tail zero of bpf_prog_info
2026-06-05 15:52 [PATCH bpf-next v3 0/3] bpf: Check tail zero of bpf_map_info and bpf_prog_info Leon Hwang
2026-06-05 15:52 ` [PATCH bpf-next v3 1/3] bpf: Check tail zero of bpf_map_info Leon Hwang
@ 2026-06-05 15:52 ` Leon Hwang
2026-06-05 16:36 ` bot+bpf-ci
2026-06-05 15:52 ` [PATCH bpf-next v3 3/3] selftests/bpf: Add tests to verify checking padding bytes for bpf_[map,prog]_info Leon Hwang
2026-06-05 22:30 ` [PATCH bpf-next v3 0/3] bpf: Check tail zero of bpf_map_info and bpf_prog_info patchwork-bot+netdevbpf
3 siblings, 1 reply; 6+ messages in thread
From: Leon Hwang @ 2026-06-05 15:52 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
Shuah Khan, Yuyang Huang, Leon Hwang, KP Singh, Dave Marchevsky,
Stanislav Fomichev, linux-kernel, linux-kselftest,
kernel-patches-bot, Mykyta Yatsenko
Since there're 4 bytes padding at the end of struct bpf_prog_info, they
won't be checked by bpf_check_uarg_tail_zero().
pahole -C bpf_prog_info ./vmlinux
struct bpf_prog_info {
...
__u32 attach_btf_obj_id; /* 220 4 */
__u32 attach_btf_id; /* 224 4 */
/* size: 232, cachelines: 4, members: 38 */
/* sum members: 224 */
/* sum bitfield members: 1 bits, bit holes: 1, sum bit holes: 31 bits */
/* padding: 4 */
/* forced alignments: 9 */
/* last cacheline: 40 bytes */
} __attribute__((__aligned__(8)));
If a future kernel extension adds a new 4-byte field, older userspace
programs allocating this structure on the stack might inadvertently pass
uninitialized stack garbage into the new field, permanently breaking
backward compatibility. -- sashiko [1]
Fix it by changing sizeof(info) to
offsetofend(struct bpf_prog_info, attach_btf_id).
And, add "__u32 :32" to the tail of struct bpf_prog_info.
[1] https://lore.kernel.org/bpf/20260513224823.6494FC19425@smtp.kernel.org/
Fixes: aba64c7da983 ("bpf: Add verified_insns to bpf_prog_info and fdinfo")
Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/uapi/linux/bpf.h | 1 +
kernel/bpf/syscall.c | 5 +++--
tools/include/uapi/linux/bpf.h | 1 +
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index e1730f449d9e..d5238df5e5eb 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -6712,6 +6712,7 @@ struct bpf_prog_info {
__u32 verified_insns;
__u32 attach_btf_obj_id;
__u32 attach_btf_id;
+ __u32 :32;
} __attribute__((aligned(8)));
struct bpf_map_info {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 89f020a44fc9..c5d4ae957e87 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5121,10 +5121,11 @@ static int bpf_prog_get_info_by_fd(struct file *file,
u32 info_len = attr->info.info_len;
struct bpf_prog_kstats stats;
char __user *uinsns;
- u32 ulen;
+ u32 ulen, len;
int err;
- err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), sizeof(info), info_len);
+ len = offsetofend(struct bpf_prog_info, attach_btf_id);
+ err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), len, info_len);
if (err)
return err;
info_len = min_t(u32, sizeof(info), info_len);
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 7caf667e86fe..3829db087449 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -6712,6 +6712,7 @@ struct bpf_prog_info {
__u32 verified_insns;
__u32 attach_btf_obj_id;
__u32 attach_btf_id;
+ __u32 :32;
} __attribute__((aligned(8)));
struct bpf_map_info {
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH bpf-next v3 2/3] bpf: Check tail zero of bpf_prog_info
2026-06-05 15:52 ` [PATCH bpf-next v3 2/3] bpf: Check tail zero of bpf_prog_info Leon Hwang
@ 2026-06-05 16:36 ` bot+bpf-ci
0 siblings, 0 replies; 6+ messages in thread
From: bot+bpf-ci @ 2026-06-05 16:36 UTC (permalink / raw)
To: leon.hwang, bpf
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, memxor,
song, yonghong.song, jolsa, shuah, yuyanghuang, leon.hwang,
kpsingh, davemarchevsky, sdf, linux-kernel, linux-kselftest,
kernel-patches-bot, yatsenko, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 3949 bytes --]
> commit acd0d2042870d7613c0c27932c41262d1c41b4e1
> Author: Leon Hwang <leon.hwang@linux.dev>
> Commit: Kernel Patches Daemon <kernel-patches-bot@fb.com>
>
> bpf: Check tail zero of bpf_prog_info
>
> Since there're 4 bytes padding at the end of struct bpf_prog_info, they
> won't be checked by bpf_check_uarg_tail_zero().
>
> pahole -C bpf_prog_info ./vmlinux
> struct bpf_prog_info {
> ...
> __u32 attach_btf_obj_id; /* 220 4 */
> __u32 attach_btf_id; /* 224 4 */
>
> /* size: 232, cachelines: 4, members: 38 */
> /* sum members: 224 */
> /* sum bitfield members: 1 bits, bit holes: 1, sum bit holes: 31 bits */
> /* padding: 4 */
> /* forced alignments: 9 */
> /* last cacheline: 40 bytes */
> } __attribute__((__aligned__(8)));
>
> If a future kernel extension adds a new 4-byte field, older userspace
> programs allocating this structure on the stack might inadvertently pass
> uninitialized stack garbage into the new field, permanently breaking
> backward compatibility. -- sashiko [1]
>
> Fix it by changing sizeof(info) to
> offsetofend(struct bpf_prog_info, attach_btf_id).
>
> And, add "__u32 :32" to the tail of struct bpf_prog_info.
>
> [1] https://lore.kernel.org/bpf/20260513224823.6494FC19425@smtp.kernel.org/
>
> Fixes: aba64c7da983 ("bpf: Add verified_insns to bpf_prog_info and fdinfo")
Is the Fixes: tag pointing to the right commit? The padding bug was
actually introduced by commit b79c9fc9551b ("bpf: implement BPF_PROG_QUERY
for BPF_LSM_CGROUP"), which added attach_btf_obj_id and attach_btf_id after
verified_insns, creating the 4 bytes of padding at the end of the structure.
Commit aba64c7da983 added verified_insns as the last field but did not
create padding.
Suggested: Fixes: b79c9fc9551b ("bpf: implement BPF_PROG_QUERY for
BPF_LSM_CGROUP")
> Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
> Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
[ ... ]
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 89f020a44fc9..c5d4ae957e87 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -5121,10 +5121,11 @@ static int bpf_prog_get_info_by_fd(struct file *file,
> u32 info_len = attr->info.info_len;
> struct bpf_prog_kstats stats;
> char __user *uinsns;
> - u32 ulen;
> + u32 ulen, len;
> int err;
>
> - err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), sizeof(info), info_len);
> + len = offsetofend(struct bpf_prog_info, attach_btf_id);
> + err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), len, info_len);
> if (err)
> return err;
> info_len = min_t(u32, sizeof(info), info_len);
Does this change break the ABI for existing deployed binaries?
Previously, expected_size was 232 (sizeof(info)). If an existing binary
passes info_len = 232 with uninitialized stack garbage in the 4-byte
padding, bpf_check_uarg_tail_zero() would see actual_size <= expected_size
(232 <= 232) and immediately return 0.
By reducing expected_size to 228, actual_size > expected_size (232 > 228),
so bpf_check_uarg_tail_zero() will actively check the 4 padding bytes and
return -E2BIG if they contain garbage. This rejects previously working
applications.
sashiko-bot and bot+bpf-ci raised this concern in v1 and v2:
https://lore.kernel.org/bpf/20260603151405.6DB111F00893@smtp.kernel.org/
While v3 adds '__u32 :32;' to prevent future field additions in the
padding space (addressing forward compatibility), the backward
compatibility concern about breaking existing binaries remains unresolved.
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27025811732
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH bpf-next v3 3/3] selftests/bpf: Add tests to verify checking padding bytes for bpf_[map,prog]_info
2026-06-05 15:52 [PATCH bpf-next v3 0/3] bpf: Check tail zero of bpf_map_info and bpf_prog_info Leon Hwang
2026-06-05 15:52 ` [PATCH bpf-next v3 1/3] bpf: Check tail zero of bpf_map_info Leon Hwang
2026-06-05 15:52 ` [PATCH bpf-next v3 2/3] bpf: Check tail zero of bpf_prog_info Leon Hwang
@ 2026-06-05 15:52 ` Leon Hwang
2026-06-05 22:30 ` [PATCH bpf-next v3 0/3] bpf: Check tail zero of bpf_map_info and bpf_prog_info patchwork-bot+netdevbpf
3 siblings, 0 replies; 6+ messages in thread
From: Leon Hwang @ 2026-06-05 15:52 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
Shuah Khan, Yuyang Huang, Leon Hwang, KP Singh, Dave Marchevsky,
Stanislav Fomichev, linux-kernel, linux-kselftest,
kernel-patches-bot
Add two tests to verify that the tail padding 4 bytes of struct
bpf_map_info and bpf_prog_info are checked in syscall.c using
bpf_check_uarg_tail_zero().
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
.../selftests/bpf/prog_tests/bpf_attr_size.c | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_attr_size.c b/tools/testing/selftests/bpf/prog_tests/bpf_attr_size.c
index 32159dc64da8..87842c4347a6 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpf_attr_size.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpf_attr_size.c
@@ -62,8 +62,63 @@ static void test_query_size_boundaries(void)
cgroup_skb_direct_packet_access__destroy(skel);
}
+static void test_map_info_tail_zero(void)
+{
+ LIBBPF_OPTS(bpf_map_create_opts, map_opts);
+ struct bpf_map_info_fake {
+ __u8 info[offsetofend(struct bpf_map_info, hash_size)];
+ __u32 pad;
+ } info = {
+ .pad = 1,
+ };
+ int map_fd, err;
+ __u32 info_len;
+
+ map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "arr", sizeof(int), 1, 1, &map_opts);
+ if (!ASSERT_GE(map_fd, 0, "bpf_map_create"))
+ return;
+
+ info_len = sizeof(info);
+ err = bpf_obj_get_info_by_fd(map_fd, &info, &info_len);
+ ASSERT_EQ(err, -E2BIG, "bpf_obj_get_info_by_fd");
+
+ close(map_fd);
+}
+
+static void test_prog_info_tail_zero(void)
+{
+ LIBBPF_OPTS(bpf_prog_load_opts, prog_opts);
+ struct bpf_insn insns[] = {
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ };
+ struct bpf_prog_info_fake {
+ __u8 info[offsetofend(struct bpf_prog_info, attach_btf_id)];
+ __u32 pad;
+ } info = {
+ .pad = 1,
+ };
+ int prog_fd, err;
+ __u32 info_len;
+
+ prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "test_prog", "GPL", insns,
+ ARRAY_SIZE(insns), &prog_opts);
+ if (!ASSERT_GE(prog_fd, 0, "bpf_prog_load"))
+ return;
+
+ info_len = sizeof(info);
+ err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+ ASSERT_EQ(err, -E2BIG, "bpf_obj_get_info_by_fd");
+
+ close(prog_fd);
+}
+
void test_bpf_attr_size(void)
{
if (test__start_subtest("query_size_boundaries"))
test_query_size_boundaries();
+ if (test__start_subtest("map_info_tail_zero"))
+ test_map_info_tail_zero();
+ if (test__start_subtest("prog_info_tail_zero"))
+ test_prog_info_tail_zero();
}
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH bpf-next v3 0/3] bpf: Check tail zero of bpf_map_info and bpf_prog_info
2026-06-05 15:52 [PATCH bpf-next v3 0/3] bpf: Check tail zero of bpf_map_info and bpf_prog_info Leon Hwang
` (2 preceding siblings ...)
2026-06-05 15:52 ` [PATCH bpf-next v3 3/3] selftests/bpf: Add tests to verify checking padding bytes for bpf_[map,prog]_info Leon Hwang
@ 2026-06-05 22:30 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-06-05 22:30 UTC (permalink / raw)
To: Leon Hwang
Cc: bpf, ast, daniel, john.fastabend, andrii, martin.lau, eddyz87,
memxor, song, yonghong.song, jolsa, shuah, yuyanghuang, kpsingh,
davemarchevsky, sdf, linux-kernel, linux-kselftest,
kernel-patches-bot
Hello:
This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:
On Fri, 5 Jun 2026 23:52:46 +0800 you wrote:
> Check the tail bytes of bpf_map_info and bpf_prog_info due to padding
> when getting map info and prog info via BPF_OBJ_GET_INFO_BY_FD, which
> was discussed in the thread
> "bpf: Check tail zero of bpf_common_attr using offsetofend" [1].
>
> Links:
> [1] https://lore.kernel.org/bpf/20260518145446.6794-2-leon.hwang@linux.dev/
>
> [...]
Here is the summary with links:
- [bpf-next,v3,1/3] bpf: Check tail zero of bpf_map_info
https://git.kernel.org/bpf/bpf-next/c/e2a49fdb1bee
- [bpf-next,v3,2/3] bpf: Check tail zero of bpf_prog_info
https://git.kernel.org/bpf/bpf-next/c/786be2b05980
- [bpf-next,v3,3/3] selftests/bpf: Add tests to verify checking padding bytes for bpf_[map,prog]_info
https://git.kernel.org/bpf/bpf-next/c/d47e67a487bf
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 6+ messages in thread