Patch "libbpf: btf_dump_type_data_check_overflow needs to consider BTF_MEMBER_BITFIELD_SIZE" 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_dump_type_data_check_overflow needs to consider BTF_MEMBER_BITFIELD_SIZE

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_dump_type_data_check_overflow-needs-to-co.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 962a4dad3907036ea3d949b437d08d44ea02718b
Author: Martin KaFai Lau <martin.lau@xxxxxxxxxx>
Date:   Thu Apr 27 18:36:38 2023 -0700

    libbpf: btf_dump_type_data_check_overflow needs to consider BTF_MEMBER_BITFIELD_SIZE
    
    [ Upstream commit c39028b333f3a3a765c5c0b9726b8e38aedf0ba1 ]
    
    The btf_dump/struct_data selftest is failing with:
    
      [...]
      test_btf_dump_struct_data:FAIL:unexpected return value dumping fs_context unexpected unexpected return value dumping fs_context: actual -7 != expected 264
      [...]
    
    The reason is in btf_dump_type_data_check_overflow(). It does not use
    BTF_MEMBER_BITFIELD_SIZE from the struct's member (btf_member). Instead,
    it is using the enum size which is 4. It had been working till the recent
    commit 4e04143c869c ("fs_context: drop the unused lsm_flags member")
    removed an integer member which also removed the 4 bytes padding at the
    end of the fs_context. Missing this 4 bytes padding exposed this bug. In
    particular, when btf_dump_type_data_check_overflow() reaches the member
    'phase', -E2BIG is returned.
    
    The fix is to pass bit_sz to btf_dump_type_data_check_overflow(). In
    btf_dump_type_data_check_overflow(), it does a different size check when
    bit_sz is not zero.
    
    The current fs_context:
    
    [3600] ENUM 'fs_context_purpose' encoding=UNSIGNED size=4 vlen=3
            'FS_CONTEXT_FOR_MOUNT' val=0
            'FS_CONTEXT_FOR_SUBMOUNT' val=1
            'FS_CONTEXT_FOR_RECONFIGURE' val=2
    [3601] ENUM 'fs_context_phase' encoding=UNSIGNED size=4 vlen=7
            'FS_CONTEXT_CREATE_PARAMS' val=0
            'FS_CONTEXT_CREATING' val=1
            'FS_CONTEXT_AWAITING_MOUNT' val=2
            'FS_CONTEXT_AWAITING_RECONF' val=3
            'FS_CONTEXT_RECONF_PARAMS' val=4
            'FS_CONTEXT_RECONFIGURING' val=5
            'FS_CONTEXT_FAILED' val=6
    [3602] STRUCT 'fs_context' size=264 vlen=21
            'ops' type_id=3603 bits_offset=0
            'uapi_mutex' type_id=235 bits_offset=64
            'fs_type' type_id=872 bits_offset=1216
            'fs_private' type_id=21 bits_offset=1280
            'sget_key' type_id=21 bits_offset=1344
            'root' type_id=781 bits_offset=1408
            'user_ns' type_id=251 bits_offset=1472
            'net_ns' type_id=984 bits_offset=1536
            'cred' type_id=1785 bits_offset=1600
            'log' type_id=3621 bits_offset=1664
            'source' type_id=42 bits_offset=1792
            'security' type_id=21 bits_offset=1856
            's_fs_info' type_id=21 bits_offset=1920
            'sb_flags' type_id=20 bits_offset=1984
            'sb_flags_mask' type_id=20 bits_offset=2016
            's_iflags' type_id=20 bits_offset=2048
            'purpose' type_id=3600 bits_offset=2080 bitfield_size=8
            'phase' type_id=3601 bits_offset=2088 bitfield_size=8
            'need_free' type_id=67 bits_offset=2096 bitfield_size=1
            'global' type_id=67 bits_offset=2097 bitfield_size=1
            'oldapi' type_id=67 bits_offset=2098 bitfield_size=1
    
    Fixes: 920d16af9b42 ("libbpf: BTF dumper support for typed data")
    Signed-off-by: Martin KaFai Lau <martin.lau@xxxxxxxxxx>
    Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
    Acked-by: Yonghong Song <yhs@xxxxxx>
    Link: https://lore.kernel.org/bpf/20230428013638.1581263-1-martin.lau@xxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
index 98cb3831aa18c..b91dd7cd4ffb0 100644
--- a/tools/lib/bpf/btf_dump.c
+++ b/tools/lib/bpf/btf_dump.c
@@ -2126,9 +2126,25 @@ static int btf_dump_type_data_check_overflow(struct btf_dump *d,
 					     const struct btf_type *t,
 					     __u32 id,
 					     const void *data,
-					     __u8 bits_offset)
+					     __u8 bits_offset,
+					     __u8 bit_sz)
 {
-	__s64 size = btf__resolve_size(d->btf, id);
+	__s64 size;
+
+	if (bit_sz) {
+		/* bits_offset is at most 7. bit_sz is at most 128. */
+		__u8 nr_bytes = (bits_offset + bit_sz + 7) / 8;
+
+		/* When bit_sz is non zero, it is called from
+		 * btf_dump_struct_data() where it only cares about
+		 * negative error value.
+		 * Return nr_bytes in success case to make it
+		 * consistent as the regular integer case below.
+		 */
+		return data + nr_bytes > d->typed_dump->data_end ? -E2BIG : nr_bytes;
+	}
+
+	size = btf__resolve_size(d->btf, id);
 
 	if (size < 0 || size >= INT_MAX) {
 		pr_warn("unexpected size [%zu] for id [%u]\n",
@@ -2281,7 +2297,7 @@ static int btf_dump_dump_type_data(struct btf_dump *d,
 {
 	int size, err = 0;
 
-	size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset);
+	size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset, bit_sz);
 	if (size < 0)
 		return size;
 	err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz);



[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