Patch "bpf: Annotate bpf_long_memcpy with data_race" has been added to the 6.1-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

    bpf: Annotate bpf_long_memcpy with data_race

to the 6.1-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:
     bpf-annotate-bpf_long_memcpy-with-data_race.patch
and it can be found in the queue-6.1 subdirectory.

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



commit f30232931a8ba03d5e9ccc4a52d92c34de6f93f6
Author: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
Date:   Tue Aug 29 22:53:52 2023 +0200

    bpf: Annotate bpf_long_memcpy with data_race
    
    [ Upstream commit 6a86b5b5cd76d2734304a0173f5f01aa8aa2025e ]
    
    syzbot reported a data race splat between two processes trying to
    update the same BPF map value via syscall on different CPUs:
    
      BUG: KCSAN: data-race in bpf_percpu_array_update / bpf_percpu_array_update
    
      write to 0xffffe8fffe7425d8 of 8 bytes by task 8257 on cpu 1:
       bpf_long_memcpy include/linux/bpf.h:428 [inline]
       bpf_obj_memcpy include/linux/bpf.h:441 [inline]
       copy_map_value_long include/linux/bpf.h:464 [inline]
       bpf_percpu_array_update+0x3bb/0x500 kernel/bpf/arraymap.c:380
       bpf_map_update_value+0x190/0x370 kernel/bpf/syscall.c:175
       generic_map_update_batch+0x3ae/0x4f0 kernel/bpf/syscall.c:1749
       bpf_map_do_batch+0x2df/0x3d0 kernel/bpf/syscall.c:4648
       __sys_bpf+0x28a/0x780
       __do_sys_bpf kernel/bpf/syscall.c:5241 [inline]
       __se_sys_bpf kernel/bpf/syscall.c:5239 [inline]
       __x64_sys_bpf+0x43/0x50 kernel/bpf/syscall.c:5239
       do_syscall_x64 arch/x86/entry/common.c:50 [inline]
       do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
       entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
      write to 0xffffe8fffe7425d8 of 8 bytes by task 8268 on cpu 0:
       bpf_long_memcpy include/linux/bpf.h:428 [inline]
       bpf_obj_memcpy include/linux/bpf.h:441 [inline]
       copy_map_value_long include/linux/bpf.h:464 [inline]
       bpf_percpu_array_update+0x3bb/0x500 kernel/bpf/arraymap.c:380
       bpf_map_update_value+0x190/0x370 kernel/bpf/syscall.c:175
       generic_map_update_batch+0x3ae/0x4f0 kernel/bpf/syscall.c:1749
       bpf_map_do_batch+0x2df/0x3d0 kernel/bpf/syscall.c:4648
       __sys_bpf+0x28a/0x780
       __do_sys_bpf kernel/bpf/syscall.c:5241 [inline]
       __se_sys_bpf kernel/bpf/syscall.c:5239 [inline]
       __x64_sys_bpf+0x43/0x50 kernel/bpf/syscall.c:5239
       do_syscall_x64 arch/x86/entry/common.c:50 [inline]
       do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
       entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
      value changed: 0x0000000000000000 -> 0xfffffff000002788
    
    The bpf_long_memcpy is used with 8-byte aligned pointers, power-of-8 size
    and forced to use long read/writes to try to atomically copy long counters.
    It is best-effort only and no barriers are here since it _will_ race with
    concurrent updates from BPF programs. The bpf_long_memcpy() is called from
    bpf(2) syscall. Marco suggested that the best way to make this known to
    KCSAN would be to use data_race() annotation.
    
    Reported-by: syzbot+97522333291430dd277f@xxxxxxxxxxxxxxxxxxxxxxxxx
    Suggested-by: Marco Elver <elver@xxxxxxxxxx>
    Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
    Acked-by: Marco Elver <elver@xxxxxxxxxx>
    Link: https://lore.kernel.org/bpf/000000000000d87a7f06040c970c@xxxxxxxxxx
    Link: https://lore.kernel.org/bpf/57628f7a15e20d502247c3b55fceb1cb2b31f266.1693342186.git.daniel@xxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index b3d3aa8437dce..1ed2ec035e779 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -301,7 +301,7 @@ static inline void bpf_long_memcpy(void *dst, const void *src, u32 size)
 
 	size /= sizeof(long);
 	while (size--)
-		*ldst++ = *lsrc++;
+		data_race(*ldst++ = *lsrc++);
 }
 
 /* copy everything but bpf_spin_lock, bpf_timer, and kptrs. There could be one of each. */



[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