In the Linux kernel, the following vulnerability has been resolved:
mm: shmem: fix data-race in shmem_getattr()
I got the following KCSAN report during syzbot testing:
================================================================== BUG: KCSAN: data-race in genericfillattr / inodesetctimecurrent
write to 0xffff888102eb3260 of 4 bytes by task 6565 on cpu 1: inodesetctimetots include/linux/fs.h:1638 [inline] inodesetctimecurrent+0x169/0x1d0 fs/inode.c:2626 shmemmknod+0x117/0x180 mm/shmem.c:3443 shmemcreate+0x34/0x40 mm/shmem.c:3497 lookupopen fs/namei.c:3578 [inline] openlastlookups fs/namei.c:3647 [inline] pathopenat+0xdbc/0x1f00 fs/namei.c:3883 dofilpopen+0xf7/0x200 fs/namei.c:3913 dosysopenat2+0xab/0x120 fs/open.c:1416 dosysopen fs/open.c:1431 [inline] _dosysopenat fs/open.c:1447 [inline] _sesysopenat fs/open.c:1442 [inline] _x64sysopenat+0xf3/0x120 fs/open.c:1442 x64syscall+0x1025/0x2d60 arch/x86/include/generated/asm/syscalls64.h:258 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0x54/0x120 arch/x86/entry/common.c:83 entrySYSCALL64after_hwframe+0x76/0x7e
read to 0xffff888102eb3260 of 4 bytes by task 3498 on cpu 0: inodegetctimensec include/linux/fs.h:1623 [inline] inodegetctime include/linux/fs.h:1629 [inline] genericfillattr+0x1dd/0x2f0 fs/stat.c:62 shmemgetattr+0x17b/0x200 mm/shmem.c:1157 vfsgetattrnosec fs/stat.c:166 [inline] vfsgetattr+0x19b/0x1e0 fs/stat.c:207 vfsstatxpath fs/stat.c:251 [inline] vfsstatx+0x134/0x2f0 fs/stat.c:315 vfsfstatat+0xec/0x110 fs/stat.c:341 _dosysnewfstatat fs/stat.c:505 [inline] _sesysnewfstatat+0x58/0x260 fs/stat.c:499 _x64sysnewfstatat+0x55/0x70 fs/stat.c:499 x64syscall+0x141f/0x2d60 arch/x86/include/generated/asm/syscalls64.h:263 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0x54/0x120 arch/x86/entry/common.c:83 entrySYSCALL64afterhwframe+0x76/0x7e
value changed: 0x2755ae53 -> 0x27ee44d3
Reported by Kernel Concurrency Sanitizer on: CPU: 0 UID: 0 PID: 3498 Comm: udevd Not tainted 6.11.0-rc6-syzkaller-00326-gd1f2d51b711a-dirty #0
When calling generic_fillattr(), if you don't hold read lock, data-race will occur in inode member variables, which can cause unexpected behavior.
Since there is no special protection when shmemgetattr() calls genericfillattr(), data-race occurs by functions such as shmemunlink() or shmemmknod(). This can cause unexpected results, so commenting it out is not enough.
Therefore, when calling genericfillattr() from shmemgetattr(), it is appropriate to protect the inode using inodelockshared() and inodeunlockshared() to prevent data-race.