]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Check tail zero of bpf_prog_info
authorLeon Hwang <leon.hwang@linux.dev>
Fri, 5 Jun 2026 15:52:48 +0000 (23:52 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 5 Jun 2026 22:21:24 +0000 (15:21 -0700)
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>
Link: https://lore.kernel.org/r/20260605155249.20772-3-leon.hwang@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
kernel/bpf/syscall.c
tools/include/uapi/linux/bpf.h

index e1730f449d9e733ed90b09be1d8c22b2a85ba8f2..d5238df5e5eb78008f8c1a51fadad1edf4c750a2 100644 (file)
@@ -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 {
index 89f020a44fc9d9b3141732274a3530e75fc7c9eb..c5d4ae957e87dbc0a6fabae88a1b3572c861324b 100644 (file)
@@ -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);
index 7caf667e86fe0e67797e25758b731b27a970cd33..3829db087449b7a48e6afa85672b6a18bf72b8ec 100644 (file)
@@ -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 {