]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
libbpf: Adjust btf_vlen() to return a __u32
authorAlan Maguire <alan.maguire@oracle.com>
Fri, 17 Apr 2026 14:30:19 +0000 (15:30 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 21 Apr 2026 00:52:48 +0000 (17:52 -0700)
Now that vlen is 24 bits, btf_vlen() must return a __u32.
Adjust use cases in libbpf accordingly.  Also add error
handling to avoid vlen overflow in btf_type_inc_vlen().

Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Link: https://lore.kernel.org/r/20260417143023.1551481-3-alan.maguire@oracle.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/lib/bpf/btf.c
tools/lib/bpf/btf.h
tools/lib/bpf/btf_dump.c
tools/lib/bpf/relo_core.c

index ceb57b46a8782a9cd58a28d9473e2e3281a4d022..267904939098c89d6592d96ac13c9b82f40bad9a 100644 (file)
@@ -421,7 +421,7 @@ static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t
 {
        __u32 l_cnt = btf->hdr.layout_len / sizeof(struct btf_layout);
        struct btf_layout *l = btf->layout;
-       __u16 vlen = btf_vlen(t);
+       __u32 vlen = btf_vlen(t);
        __u32 kind = btf_kind(t);
 
        /* Fall back to base BTF if needed as they share layout information */
@@ -454,7 +454,7 @@ static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t
 static int btf_type_size(const struct btf *btf, const struct btf_type *t)
 {
        const int base_size = sizeof(struct btf_type);
-       __u16 vlen = btf_vlen(t);
+       __u32 vlen = btf_vlen(t);
 
        switch (btf_kind(t)) {
        case BTF_KIND_FWD:
@@ -506,7 +506,7 @@ static int btf_bswap_type_rest(struct btf_type *t)
        struct btf_array *a;
        struct btf_param *p;
        struct btf_enum *e;
-       __u16 vlen = btf_vlen(t);
+       __u32 vlen = btf_vlen(t);
        int i;
 
        switch (btf_kind(t)) {
@@ -1007,7 +1007,7 @@ int btf__align_of(const struct btf *btf, __u32 id)
        case BTF_KIND_STRUCT:
        case BTF_KIND_UNION: {
                const struct btf_member *m = btf_members(t);
-               __u16 vlen = btf_vlen(t);
+               __u32 vlen = btf_vlen(t);
                int i, max_align = 1, align;
 
                for (i = 0; i < vlen; i++, m++) {
@@ -2121,9 +2121,12 @@ static void *btf_add_type_mem(struct btf *btf, size_t add_sz)
                              btf->hdr.type_len, UINT_MAX, add_sz);
 }
 
-static void btf_type_inc_vlen(struct btf_type *t)
+static int btf_type_inc_vlen(struct btf_type *t)
 {
+       if (btf_vlen(t) == BTF_MAX_VLEN)
+               return -ENOSPC;
        t->info = btf_type_info(btf_kind(t), btf_vlen(t) + 1, btf_kflag(t));
+       return 0;
 }
 
 static void btf_hdr_update_type_len(struct btf *btf, int new_len)
@@ -2652,6 +2655,8 @@ int btf__add_field(struct btf *btf, const char *name, int type_id,
        t = btf_last_type(btf);
        if (!btf_is_composite(t))
                return libbpf_err(-EINVAL);
+       if (btf_vlen(t) == BTF_MAX_VLEN)
+               return libbpf_err(-ENOSPC);
 
        if (validate_type_id(type_id))
                return libbpf_err(-EINVAL);
@@ -2686,6 +2691,7 @@ int btf__add_field(struct btf *btf, const char *name, int type_id,
 
        /* btf_add_type_mem can invalidate t pointer */
        t = btf_last_type(btf);
+
        /* update parent type's vlen and kflag */
        t->info = btf_type_info(btf_kind(t), btf_vlen(t) + 1, is_bitfield || btf_kflag(t));
 
@@ -2796,7 +2802,9 @@ int btf__add_enum_value(struct btf *btf, const char *name, __s64 value)
 
        /* update parent type's vlen */
        t = btf_last_type(btf);
-       btf_type_inc_vlen(t);
+       err = btf_type_inc_vlen(t);
+       if (err)
+               return libbpf_err(err);
 
        /* if negative value, set signedness to signed */
        if (value < 0)
@@ -2873,7 +2881,9 @@ int btf__add_enum64_value(struct btf *btf, const char *name, __u64 value)
 
        /* update parent type's vlen */
        t = btf_last_type(btf);
-       btf_type_inc_vlen(t);
+       err = btf_type_inc_vlen(t);
+       if (err)
+               return libbpf_err(err);
 
        btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
        return 0;
@@ -3115,7 +3125,9 @@ int btf__add_func_param(struct btf *btf, const char *name, int type_id)
 
        /* update parent type's vlen */
        t = btf_last_type(btf);
-       btf_type_inc_vlen(t);
+       err = btf_type_inc_vlen(t);
+       if (err)
+               return libbpf_err(err);
 
        btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
        return 0;
@@ -3257,7 +3269,9 @@ int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __
 
        /* update parent type's vlen */
        t = btf_last_type(btf);
-       btf_type_inc_vlen(t);
+       err = btf_type_inc_vlen(t);
+       if (err)
+               return libbpf_err(err);
 
        btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
        return 0;
@@ -4311,7 +4325,7 @@ static long btf_hash_enum(struct btf_type *t)
 static bool btf_equal_enum_members(struct btf_type *t1, struct btf_type *t2)
 {
        const struct btf_enum *m1, *m2;
-       __u16 vlen;
+       __u32 vlen;
        int i;
 
        vlen = btf_vlen(t1);
@@ -4329,7 +4343,7 @@ static bool btf_equal_enum_members(struct btf_type *t1, struct btf_type *t2)
 static bool btf_equal_enum64_members(struct btf_type *t1, struct btf_type *t2)
 {
        const struct btf_enum64 *m1, *m2;
-       __u16 vlen;
+       __u32 vlen;
        int i;
 
        vlen = btf_vlen(t1);
@@ -4406,7 +4420,7 @@ static long btf_hash_struct(struct btf_type *t)
 static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2)
 {
        const struct btf_member *m1, *m2;
-       __u16 vlen;
+       __u32 vlen;
        int i;
 
        if (!btf_equal_common(t1, t2))
@@ -4482,7 +4496,7 @@ static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2)
 static long btf_hash_fnproto(struct btf_type *t)
 {
        const struct btf_param *member = btf_params(t);
-       __u16 vlen = btf_vlen(t);
+       __u32 vlen = btf_vlen(t);
        long h = btf_hash_common(t);
        int i;
 
@@ -4504,7 +4518,7 @@ static long btf_hash_fnproto(struct btf_type *t)
 static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2)
 {
        const struct btf_param *m1, *m2;
-       __u16 vlen;
+       __u32 vlen;
        int i;
 
        if (!btf_equal_common(t1, t2))
@@ -4530,7 +4544,7 @@ static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2)
 static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2)
 {
        const struct btf_param *m1, *m2;
-       __u16 vlen;
+       __u32 vlen;
        int i;
 
        /* skip return type ID */
@@ -5077,7 +5091,7 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
        case BTF_KIND_STRUCT:
        case BTF_KIND_UNION: {
                const struct btf_member *cand_m, *canon_m;
-               __u16 vlen;
+               __u32 vlen;
 
                if (!btf_shallow_equal_struct(cand_type, canon_type))
                        return 0;
@@ -5105,7 +5119,7 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
 
        case BTF_KIND_FUNC_PROTO: {
                const struct btf_param *cand_p, *canon_p;
-               __u16 vlen;
+               __u32 vlen;
 
                if (!btf_compat_fnproto(cand_type, canon_type))
                        return 0;
@@ -5439,7 +5453,7 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
 
        case BTF_KIND_FUNC_PROTO: {
                struct btf_param *param;
-               __u16 vlen;
+               __u32 vlen;
                int i;
 
                ref_type_id = btf_dedup_ref_type(d, t->type);
index a1f8deca2603395c8f36b3a85671678074924c61..1a31f2da947f8ade1271e14343c68c25ee260451 100644 (file)
@@ -435,7 +435,7 @@ static inline __u16 btf_kind(const struct btf_type *t)
        return BTF_INFO_KIND(t->info);
 }
 
-static inline __u16 btf_vlen(const struct btf_type *t)
+static inline __u32 btf_vlen(const struct btf_type *t)
 {
        return BTF_INFO_VLEN(t->info);
 }
index 53c6624161d79738b842e0310340816950c4498c..cc1ba65bb6c5ac21d9c0515a0df32383aa6ed6cb 100644 (file)
@@ -316,7 +316,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
 {
        int i, j, n = btf__type_cnt(d->btf);
        const struct btf_type *t;
-       __u16 vlen;
+       __u32 vlen;
 
        for (i = d->last_id + 1; i < n; i++) {
                t = btf__type_by_id(d->btf, i);
@@ -485,7 +485,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
         */
        struct btf_dump_type_aux_state *tstate = &d->type_states[id];
        const struct btf_type *t;
-       __u16 vlen;
+       __u32 vlen;
        int err, i;
 
        /* return true, letting typedefs know that it's ok to be emitted */
@@ -798,7 +798,7 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
                 */
                if (top_level_def || t->name_off == 0) {
                        const struct btf_member *m = btf_members(t);
-                       __u16 vlen = btf_vlen(t);
+                       __u32 vlen = btf_vlen(t);
                        int i, new_cont_id;
 
                        new_cont_id = t->name_off == 0 ? cont_id : id;
@@ -820,7 +820,7 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
                break;
        case BTF_KIND_FUNC_PROTO: {
                const struct btf_param *p = btf_params(t);
-               __u16 n = btf_vlen(t);
+               __u32 n = btf_vlen(t);
                int i;
 
                btf_dump_emit_type(d, t->type, cont_id);
@@ -839,7 +839,7 @@ static bool btf_is_struct_packed(const struct btf *btf, __u32 id,
 {
        const struct btf_member *m;
        int max_align = 1, align, i, bit_sz;
-       __u16 vlen;
+       __u32 vlen;
 
        m = btf_members(t);
        vlen = btf_vlen(t);
@@ -973,7 +973,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
        bool is_struct = btf_is_struct(t);
        bool packed, prev_bitfield = false;
        int align, i, off = 0;
-       __u16 vlen = btf_vlen(t);
+       __u32 vlen = btf_vlen(t);
 
        align = btf__align_of(d->btf, id);
        packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0;
@@ -1064,7 +1064,7 @@ static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
 
 static void btf_dump_emit_enum32_val(struct btf_dump *d,
                                     const struct btf_type *t,
-                                    int lvl, __u16 vlen)
+                                    int lvl, __u32 vlen)
 {
        const struct btf_enum *v = btf_enum(t);
        bool is_signed = btf_kflag(t);
@@ -1089,7 +1089,7 @@ static void btf_dump_emit_enum32_val(struct btf_dump *d,
 
 static void btf_dump_emit_enum64_val(struct btf_dump *d,
                                     const struct btf_type *t,
-                                    int lvl, __u16 vlen)
+                                    int lvl, __u32 vlen)
 {
        const struct btf_enum64 *v = btf_enum64(t);
        bool is_signed = btf_kflag(t);
@@ -1122,7 +1122,7 @@ static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
                                   const struct btf_type *t,
                                   int lvl)
 {
-       __u16 vlen = btf_vlen(t);
+       __u32 vlen = btf_vlen(t);
 
        btf_dump_printf(d, "enum%s%s",
                        t->name_off ? " " : "",
@@ -1542,7 +1542,7 @@ static void btf_dump_emit_type_chain(struct btf_dump *d,
                }
                case BTF_KIND_FUNC_PROTO: {
                        const struct btf_param *p = btf_params(t);
-                       __u16 vlen = btf_vlen(t);
+                       __u32 vlen = btf_vlen(t);
                        int i;
 
                        /*
@@ -2159,7 +2159,7 @@ static int btf_dump_struct_data(struct btf_dump *d,
                                const void *data)
 {
        const struct btf_member *m = btf_members(t);
-       __u16 n = btf_vlen(t);
+       __u32 n = btf_vlen(t);
        int i, err = 0;
 
        /* note that we increment depth before calling btf_dump_print() below;
@@ -2449,7 +2449,7 @@ static int btf_dump_type_data_check_zero(struct btf_dump *d,
        case BTF_KIND_STRUCT:
        case BTF_KIND_UNION: {
                const struct btf_member *m = btf_members(t);
-               __u16 n = btf_vlen(t);
+               __u32 n = btf_vlen(t);
 
                /* if any struct/union member is non-zero, the struct/union
                 * is considered non-zero and dumped.
index 0ccc8f548cbaabd23121aaf120989111be17a75f..6ae3f2a15ad0cf382880aea99e4179f019099a04 100644 (file)
@@ -191,8 +191,8 @@ recur:
        case BTF_KIND_FUNC_PROTO: {
                struct btf_param *local_p = btf_params(local_type);
                struct btf_param *targ_p = btf_params(targ_type);
-               __u16 local_vlen = btf_vlen(local_type);
-               __u16 targ_vlen = btf_vlen(targ_type);
+               __u32 local_vlen = btf_vlen(local_type);
+               __u32 targ_vlen = btf_vlen(targ_type);
                int i, err;
 
                if (local_vlen != targ_vlen)
@@ -1457,8 +1457,8 @@ static bool bpf_core_names_match(const struct btf *local_btf, size_t local_name_
 static int bpf_core_enums_match(const struct btf *local_btf, const struct btf_type *local_t,
                                const struct btf *targ_btf, const struct btf_type *targ_t)
 {
-       __u16 local_vlen = btf_vlen(local_t);
-       __u16 targ_vlen = btf_vlen(targ_t);
+       __u32 local_vlen = btf_vlen(local_t);
+       __u32 targ_vlen = btf_vlen(targ_t);
        int i, j;
 
        if (local_t->size != targ_t->size)
@@ -1498,8 +1498,8 @@ static int bpf_core_composites_match(const struct btf *local_btf, const struct b
                                     bool behind_ptr, int level)
 {
        const struct btf_member *local_m = btf_members(local_t);
-       __u16 local_vlen = btf_vlen(local_t);
-       __u16 targ_vlen = btf_vlen(targ_t);
+       __u32 local_vlen = btf_vlen(local_t);
+       __u32 targ_vlen = btf_vlen(targ_t);
        int i, j, err;
 
        if (local_vlen > targ_vlen)
@@ -1674,8 +1674,8 @@ recur:
        case BTF_KIND_FUNC_PROTO: {
                struct btf_param *local_p = btf_params(local_t);
                struct btf_param *targ_p = btf_params(targ_t);
-               __u16 local_vlen = btf_vlen(local_t);
-               __u16 targ_vlen = btf_vlen(targ_t);
+               __u32 local_vlen = btf_vlen(local_t);
+               __u32 targ_vlen = btf_vlen(targ_t);
                int i, err;
 
                if (local_k != targ_k)