From nobody Wed Apr 8 01:16:35 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ACD2CB652; Wed, 11 Mar 2026 02:54:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773197695; cv=none; b=jOgCq3G6LWv1UZD2Vd6v9FnVd26lR71s1WARFI/U5wZoTWWbYTfOQD0YqRiXfIPT2dTjDmirRCJ7fHb3tQqVhX6/MWOKNMgd+cueAIyxRu0pxD9043jL5ctYTjEOHBduDngtxvdUfvYZBcj8Om29UjOR4+McOzlvoGjpg1YPFbY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773197695; c=relaxed/simple; bh=IgnFbRqg1z9IXEYVmAAUq/7TuevJW0UIhYq7v8N6T9U=; h=Date:From:To:Subject:Content-Type:MIME-Version:Message-ID; b=Un/58HaM9Vx+fB4We9bndqezrJV8nYHfuXlOENDBlFej6LgmielRFXGUvpwseTIMRJ9s53Oya7X3cVa8J+VxZctcOAZXSoHtKob/6uk7NeE0k4pGk/OA3gCoi7RDva5DBcVZBz3rYfDsRGxUrux5EmHDiMVEf+b0lhZzi7zGo3I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=QCypl6f0; arc=none smtp.client-ip=220.197.31.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="QCypl6f0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=Date:From:To:Subject:Content-Type:MIME-Version: Message-ID; bh=IgnFbRqg1z9IXEYVmAAUq/7TuevJW0UIhYq7v8N6T9U=; b=Q Cypl6f0tO/5mWeihUSGsxmR94uxgvuvW8vARgYVf/sNoAMaVtfxQkGlMebIGDGOX P8cnnUl97KWPNkLpHkhG84T7LZ3KnS8svzjzkzwZ9v5n8r1qP+4FDMrWgTvs2TkZ UE/9ZNZ1+3N5yFNQUSVX38dNvctpP8qVUa4hqZ3BCE= Received: from luckd0g$163.com ( [183.205.138.18] ) by ajax-webmail-wmsvr-40-146 (Coremail) ; Wed, 11 Mar 2026 10:54:28 +0800 (CST) Date: Wed, 11 Mar 2026 10:54:28 +0800 (CST) From: "Jianzhou Zhao" To: jack@suse.cz, viro@zeniv.linux.org.uk, brauner@kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: KCSAN: data-race in path_lookupat / vfs_rename X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2023.4-cmXT build 20251222(83accb85) Copyright (c) 2002-2026 www.mailtech.cn 163com X-NTES-SC: AL_Qu2cAf2SuE4t7iSfZekfmU4Rhug7UMO3uf8n24JfPJ9wjCzr5C4MZHpGN2Py3OuVMC+gqhiXXAlB7sV7cJNobacNuDlrHiId4MZjN1eutu+vig== Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <61ff6def.2d0d.19cdad1307e.Coremail.luckd0g@163.com> X-Coremail-Locale: zh_CN X-CM-TRANSID: kigvCgD3H2xk2bBp9d91AA--.40679W X-CM-SenderInfo: poxfyvkqj6il2tof0z/xtbC9gQWoGmw2WQRgwAA3y X-Coremail-Antispam: 1U5529EdanIXcx71UUUUU7vcSsGvfC2KfnxnUU== Content-Type: text/plain; charset="utf-8" Subject: [BUG] fs/namei: KCSAN: data-race in path_lookupat / vfs_rename (`d= _flags`) Dear VFS Maintainers, Our fuzzing tool, RacePilot, has detected a data race in the VFS subsystem = on a 6.18 kernel version (`6.18.0-08691-g2061f18ad76e-dirty`).=20 The race occurs between `vfs_rename()` modifying a victim dentry's `d_flags= ` via `dont_mount()` and a concurrent path lookup (`path_lookupat()`) execu= ting lockless reads on the same `d_flags` via `d_managed()`. ### Call Trace & Context ``` BUG: KCSAN: data-race in path_lookupat / vfs_rename write to 0xffff88802d62b180 of 4 bytes by task 4204 on cpu 0: dont_mount include/linux/dcache.h:391 [inline] vfs_rename+0xf03/0x13a0 fs/namei.c:5963 do_renameat2+0x6a9/0x8e0 fs/namei.c:6072 ... read to 0xffff88802d62b180 of 4 bytes by task 4691 on cpu 1: d_managed include/linux/dcache.h:412 [inline] step_into fs/namei.c:2102 [inline] walk_component fs/namei.c:2258 [inline] lookup_last fs/namei.c:2753 [inline] path_lookupat+0x1fc/0x740 fs/namei.c:2777 ... value changed: 0x00300080 -> 0x00004180 ``` #### Execution Flow & Code Context: **1. The Write Path (`vfs_rename` -> `dont_mount`)** During a rename operation, if a target (victim) dentry is going to be repla= ced, `vfs_rename` unmounts any mounts attached to it: ```c 5978: if (!(flags & RENAME_EXCHANGE) && target) { 5979: if (is_dir) { 5980: shrink_dcache_parent(new_dentry); 5981: target->i_flags |=3D S_DEAD; 5982: } 5983: dont_mount(new_dentry); // <--- Invokes dont_mount on the victim 5984: detach_mounts(new_dentry); 5985: } ``` Inside `dont_mount(struct dentry *dentry)` (`include/linux/dcache.h`), `d_f= lags` is updated while holding the `d_lock`: ```c 388: static inline void dont_mount(struct dentry *dentry) 389: { 390: spin_lock(&dentry->d_lock); 391: dentry->d_flags |=3D DCACHE_CANT_MOUNT; // <--- Read-Modify-Write 392: spin_unlock(&dentry->d_lock); 393: } ``` **2. The Read Path (`path_lookupat` -> `step_into` -> `d_managed`)** Concurrently, a separate thread traversing the filesystem performs a path l= ookup and inspects the same intermediate dentry (the rename victim) within = `step_into()`. It tests if the dentry needs mount-point translation by call= ing `d_managed()`: ```c 412: static inline bool d_managed(const struct dentry *dentry) 413: { 414: return dentry->d_flags & DCACHE_MANAGED_DENTRY; // <--- Lockless Read 415: } ``` ### Root Cause Analysis The data race is triggered because `d_managed()` executes a plain read of `= dentry->d_flags` without holding `d_lock` (or using `READ_ONCE`), while `do= nt_mount()` concurrently modifies `dentry->d_flags` using a plain read-modi= fy-write operation (`|=3D DCACHE_CANT_MOUNT`).=20 Although `dont_mount()` properly protects the write within a `spin_lock`, t= he lockless reader is oblivious to it. KCSAN identifies this as a data race= because the plain read in `d_managed()` can overlap with the unlocked port= ion of the compiler's emitted store sequence in another CPU. Regrettably, we were unable to create a reproduction program for this bug. ### Potential Impact While a torn read of a 32-bit aligned integer is highly unlikely on most mo= dern architectures, plain concurrent access constitutes undefined behavior = under the C memory model. The compiler might apply unforeseen transformatio= ns capable of producing a stale or transient state representation. However,= pragmatically speaking, since the victim dentry is concurrently being purg= ed/renamed, misinterpreting the managed flags would likely lead to subseque= nt validation failures upstream within namei.c, causing the traversal to bo= unce to slow paths safely. Therefore, we evaluate the severity of this issu= e as a minor data race that primarily risks undefined behavior and triggers= KCSAN warnings. ### Proposed Fix To silence the KCSAN warning and adhere securely to kernel concurrency prac= tices, the lockless read of `d_flags` in `d_managed()` should be explicitly= annotated using `data_race()` or, more robustly, `READ_ONCE()`. Using `REA= D_ONCE()` guarantees single-instruction load semantics preventing compiler = optimizations that might induce tearing. ```diff --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -411,7 +411,7 @@ extern void dput(struct dentry *); =20 static inline bool d_managed(const struct dentry *dentry) { - return dentry->d_flags & DCACHE_MANAGED_DENTRY; + return READ_ONCE(dentry->d_flags) & DCACHE_MANAGED_DENTRY; } ``` (Alternatively, using `data_race()` if no load-tearing dangers exist in the= ory on the supported architectures, depending on VFS lockless scaling conve= ntions for d_flags). We would be highly honored if this could be of any help. Best regards, [Your Name/Team] RacePilot Team