Patch "libbpf: Btf dedup identical struct test needs check for nested structs/arrays" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    libbpf: Btf dedup identical struct test needs check for nested structs/arrays

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     libbpf-btf-dedup-identical-struct-test-needs-check-f.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit c7561e9b85714277be8d129685211594f28b35fe
Author: Alan Maguire <alan.maguire@xxxxxxxxxx>
Date:   Mon Oct 24 15:38:29 2022 +0100

    libbpf: Btf dedup identical struct test needs check for nested structs/arrays
    
    [ Upstream commit f3c51fe02c55bd944662714e5b91b96dc271ad9f ]
    
    When examining module BTF, it is common to see core kernel structures
    such as sk_buff, net_device duplicated in the module.  After adding
    debug messaging to BTF it turned out that much of the problem
    was down to the identical struct test failing during deduplication;
    sometimes the compiler adds identical structs.  However
    it turns out sometimes that type ids of identical struct members
    can also differ, even when the containing structs are still identical.
    
    To take an example, for struct sk_buff, debug messaging revealed
    that the identical struct matching was failing for the anon
    struct "headers"; specifically for the first field:
    
    __u8       __pkt_type_offset[0]; /*   128     0 */
    
    Looking at the code in BTF deduplication, we have code that guards
    against the possibility of identical struct definitions, down to
    type ids, and identical array definitions.  However in this case
    we have a struct which is being defined twice but does not have
    identical type ids since each duplicate struct has separate type
    ids for the above array member.   A similar problem (though not
    observed) could occur for struct-in-struct.
    
    The solution is to make the "identical struct" test check members
    not just for matching ids, but to also check if they in turn are
    identical structs or arrays.
    
    The results of doing this are quite dramatic (for some modules
    at least); I see the number of type ids drop from around 10000
    to just over 1000 in one module for example.
    
    For testing use latest pahole or apply [1], otherwise dedups
    can fail for the reasons described there.
    
    Also fix return type of btf_dedup_identical_arrays() as
    suggested by Andrii to match boolean return type used
    elsewhere.
    
    Fixes: efdd3eb8015e ("libbpf: Accommodate DWARF/compiler bug with duplicated structs")
    Signed-off-by: Alan Maguire <alan.maguire@xxxxxxxxxx>
    Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
    Link: https://lore.kernel.org/bpf/1666622309-22289-1-git-send-email-alan.maguire@xxxxxxxxxx
    
    [1] https://lore.kernel.org/bpf/1666364523-9648-1-git-send-email-alan.maguire
    
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 5f3d20ae66d5..3ed759f53e7c 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -3718,14 +3718,14 @@ static inline __u16 btf_fwd_kind(struct btf_type *t)
 }
 
 /* Check if given two types are identical ARRAY definitions */
-static int btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
+static bool btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
 {
 	struct btf_type *t1, *t2;
 
 	t1 = btf_type_by_id(d->btf, id1);
 	t2 = btf_type_by_id(d->btf, id2);
 	if (!btf_is_array(t1) || !btf_is_array(t2))
-		return 0;
+		return false;
 
 	return btf_equal_array(t1, t2);
 }
@@ -3749,7 +3749,9 @@ static bool btf_dedup_identical_structs(struct btf_dedup *d, __u32 id1, __u32 id
 	m1 = btf_members(t1);
 	m2 = btf_members(t2);
 	for (i = 0, n = btf_vlen(t1); i < n; i++, m1++, m2++) {
-		if (m1->type != m2->type)
+		if (m1->type != m2->type &&
+		    !btf_dedup_identical_arrays(d, m1->type, m2->type) &&
+		    !btf_dedup_identical_structs(d, m1->type, m2->type))
 			return false;
 	}
 	return true;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux