]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Fix task_local_data data allocation size
authorAmery Hung <ameryhung@gmail.com>
Tue, 31 Mar 2026 21:35:51 +0000 (14:35 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 2 Apr 2026 22:11:08 +0000 (15:11 -0700)
Currently, when allocating memory for data, size of tld_data_u->start
is not taken into account. This may cause OOB access. Fixed it by adding
the non-flexible array part of tld_data_u.

Besides, explicitly align tld_data_u->data to 8 bytes in case some
fields are added before data in the future. It could break the
assumption that every data field is 8 byte aligned and
sizeof(tld_data_u) will no longer be equal to
offsetof(struct tld_data_u, data), which we use interchangeably.

Signed-off-by: Amery Hung <ameryhung@gmail.com>
Acked-by: Sun Jian <sun.jian.kdev@gmail.com>
Link: https://lore.kernel.org/r/20260331213555.1993883-2-ameryhung@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/task_local_data.h
tools/testing/selftests/bpf/progs/task_local_data.bpf.h

index 7819f318b2fbd7a665feec9fdf667aa5ee394a63..a52d8b5494253bf0dca3a9f6911411b98025943c 100644 (file)
@@ -90,7 +90,7 @@ typedef struct {
 
 struct tld_metadata {
        char name[TLD_NAME_LEN];
-       _Atomic __u16 size;
+       _Atomic __u16 size; /* size of tld_data_u->data */
 };
 
 struct tld_meta_u {
@@ -101,7 +101,7 @@ struct tld_meta_u {
 
 struct tld_data_u {
        __u64 start; /* offset of tld_data_u->data in a page */
-       char data[];
+       char data[] __attribute__((aligned(8)));
 };
 
 struct tld_map_value {
@@ -158,6 +158,7 @@ static int __tld_init_data_p(int map_fd)
        struct tld_data_u *data;
        void *data_alloc = NULL;
        int err, tid_fd = -1;
+       size_t size;
 
        tid_fd = syscall(SYS_pidfd_open, sys_gettid(), O_EXCL);
        if (tid_fd < 0) {
@@ -173,9 +174,10 @@ static int __tld_init_data_p(int map_fd)
         * tld_meta_p->size = TLD_DYN_DATA_SIZE +
         *          total size of TLDs defined via TLD_DEFINE_KEY()
         */
-       data_alloc = (use_aligned_alloc || tld_meta_p->size * 2 >= TLD_PAGE_SIZE) ?
-               aligned_alloc(TLD_PAGE_SIZE, tld_meta_p->size) :
-               malloc(tld_meta_p->size * 2);
+       size = tld_meta_p->size + sizeof(struct tld_data_u);
+       data_alloc = (use_aligned_alloc || size * 2 >= TLD_PAGE_SIZE) ?
+               aligned_alloc(TLD_PAGE_SIZE, size) :
+               malloc(size * 2);
        if (!data_alloc) {
                err = -ENOMEM;
                goto out;
index 8b6f7af43648aba4843f7824d4c6d55cf1636bcb..1f396711f487135cf055101123dcce5da67948e3 100644 (file)
@@ -87,7 +87,7 @@ struct tld_meta_u {
 
 struct tld_data_u {
        __u64 start; /* offset of tld_data_u->data in a page */
-       char data[__PAGE_SIZE - sizeof(__u64)];
+       char data[__PAGE_SIZE - sizeof(__u64)] __attribute__((aligned(8)));
 };
 
 struct tld_map_value {