[PATCH] Xarray: Fix race in xa_get_order()

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

 



Hello! This is my first patch ever, so please bear with me if I make some rookie
mistakes. I've tried my best to follow the documentation :) 

KCSAN detects data-race in xa_get_order:1779 / xas_store:819. xas_store() uses
rcu_assign_pointer() for the slots pointer, but xa_get_order() does not
use rcu to access the same pointer, resulting in a value change from 
0x0000000000000000 -> 0xffffea0000488f00.

Use rcu_dereference() to access the rcu slots pointer in xa_get_order() to
avoid KCSAN warnings. 

Full bug report:
==================================================================
BUG: KCSAN: data-race in xa_get_order / xas_store

write (marked) to 0xffff88800b4cb150 of 8 bytes by task 239 on cpu 1:
 xas_store+0x6c8/0x11d0 lib/xarray.c:819
 __filemap_add_folio+0x61a/0xb30 mm/filemap.c:898
 filemap_add_folio+0x69/0x160 mm/filemap.c:937
 page_cache_ra_unbounded+0x134/0x3b0 mm/readahead.c:250
 do_page_cache_ra mm/readahead.c:299 [inline]
 page_cache_ra_order+0xc4/0xe0 mm/readahead.c:546
 do_sync_mmap_readahead mm/filemap.c:3150 [inline]
 filemap_fault+0xe45/0x1960 mm/filemap.c:3242
 __do_fault+0x8e/0x2c0 mm/memory.c:4266
 do_read_fault mm/memory.c:4629 [inline]
 do_fault mm/memory.c:4763 [inline]
 do_pte_missing mm/memory.c:3731 [inline]
 handle_pte_fault mm/memory.c:5039 [inline]
 __handle_mm_fault+0xd96/0x1df0 mm/memory.c:5180
 handle_mm_fault+0x227/0x6a0 mm/memory.c:5345
 do_user_addr_fault+0x2d5/0xf30 arch/x86/mm/fault.c:1364
 handle_page_fault arch/x86/mm/fault.c:1507 [inline]
 exc_page_fault+0xa9/0x330 arch/x86/mm/fault.c:1563
 asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:570

read to 0xffff88800b4cb150 of 8 bytes by task 235 on cpu 0:
 xa_get_order+0x1a2/0x400 lib/xarray.c:1779
 __filemap_add_folio+0x44c/0xb30 mm/filemap.c:870
 filemap_add_folio+0x69/0x160 mm/filemap.c:937
 page_cache_ra_unbounded+0x134/0x3b0 mm/readahead.c:250
 do_page_cache_ra mm/readahead.c:299 [inline]
 page_cache_ra_order+0xc4/0xe0 mm/readahead.c:546
 do_sync_mmap_readahead mm/filemap.c:3150 [inline]
 filemap_fault+0xe45/0x1960 mm/filemap.c:3242
 __do_fault+0x8e/0x2c0 mm/memory.c:4266
 do_read_fault mm/memory.c:4629 [inline]
 do_fault mm/memory.c:4763 [inline]
 do_pte_missing mm/memory.c:3731 [inline]
 handle_pte_fault mm/memory.c:5039 [inline]
 __handle_mm_fault+0xd96/0x1df0 mm/memory.c:5180
 handle_mm_fault+0x227/0x6a0 mm/memory.c:5345
 do_user_addr_fault+0x2d5/0xf30 arch/x86/mm/fault.c:1364
 handle_page_fault arch/x86/mm/fault.c:1507 [inline]
 exc_page_fault+0xa9/0x330 arch/x86/mm/fault.c:1563
 asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:570

value changed: 0x0000000000000000 -> 0xffffea0000488f00

Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 235 Comm: gcc Not tainted 6.7.0-g65c265174d11-dirty #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
==================================================================

Signed-off-by: Han Xing Yi <hxingyi104@xxxxxxxxx>
---
 lib/xarray.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/xarray.c b/lib/xarray.c
index 39f07bfc4dcc..7fc225f3cf4e 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -1776,7 +1776,7 @@ int xa_get_order(struct xarray *xa, unsigned long index)
 
 		if (slot >= XA_CHUNK_SIZE)
 			break;
-		if (!xa_is_sibling(xas.xa_node->slots[slot]))
+		if (!xa_is_sibling(rcu_dereference(xas.xa_node->slots[slot])))
 			break;
 		order++;
 	}
-- 
2.34.1





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux