Patch "9p/trans_fd: Annotate data-racy writes to file::f_flags" 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

    9p/trans_fd: Annotate data-racy writes to file::f_flags

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:
     9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.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 60a2e7a6c27ddd96ad3d3521738a65379c0d7192
Author: Marco Elver <elver@xxxxxxxxxx>
Date:   Wed Oct 25 19:34:43 2023 +0900

    9p/trans_fd: Annotate data-racy writes to file::f_flags
    
    [ Upstream commit 355f074609dbf3042900ea9d30fcd2b0c323a365 ]
    
    syzbot reported:
    
     | BUG: KCSAN: data-race in p9_fd_create / p9_fd_create
     |
     | read-write to 0xffff888130fb3d48 of 4 bytes by task 15599 on cpu 0:
     |  p9_fd_open net/9p/trans_fd.c:842 [inline]
     |  p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092
     |  p9_client_create+0x595/0xa70 net/9p/client.c:1010
     |  v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410
     |  v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123
     |  legacy_get_tree+0x74/0xd0 fs/fs_context.c:611
     |  vfs_get_tree+0x51/0x190 fs/super.c:1519
     |  do_new_mount+0x203/0x660 fs/namespace.c:3335
     |  path_mount+0x496/0xb30 fs/namespace.c:3662
     |  do_mount fs/namespace.c:3675 [inline]
     |  __do_sys_mount fs/namespace.c:3884 [inline]
     |  [...]
     |
     | read-write to 0xffff888130fb3d48 of 4 bytes by task 15563 on cpu 1:
     |  p9_fd_open net/9p/trans_fd.c:842 [inline]
     |  p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092
     |  p9_client_create+0x595/0xa70 net/9p/client.c:1010
     |  v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410
     |  v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123
     |  legacy_get_tree+0x74/0xd0 fs/fs_context.c:611
     |  vfs_get_tree+0x51/0x190 fs/super.c:1519
     |  do_new_mount+0x203/0x660 fs/namespace.c:3335
     |  path_mount+0x496/0xb30 fs/namespace.c:3662
     |  do_mount fs/namespace.c:3675 [inline]
     |  __do_sys_mount fs/namespace.c:3884 [inline]
     |  [...]
     |
     | value changed: 0x00008002 -> 0x00008802
    
    Within p9_fd_open(), O_NONBLOCK is added to f_flags of the read and
    write files. This may happen concurrently if e.g. mounting process
    modifies the fd in another thread.
    
    Mark the plain read-modify-writes as intentional data-races, with the
    assumption that the result of executing the accesses concurrently will
    always result in the same result despite the accesses themselves not
    being atomic.
    
    Reported-by: syzbot+e441aeeb422763cc5511@xxxxxxxxxxxxxxxxxxxxxxxxx
    Signed-off-by: Marco Elver <elver@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/ZO38mqkS0TYUlpFp@xxxxxxxxxxxxxxxx
    Signed-off-by: Dominique Martinet <asmadeus@xxxxxxxxxxxxx>
    Message-ID: <20231025103445.1248103-1-asmadeus@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 5a1aecf7fe487..a69422366a235 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -833,14 +833,21 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
 		goto out_free_ts;
 	if (!(ts->rd->f_mode & FMODE_READ))
 		goto out_put_rd;
-	/* prevent workers from hanging on IO when fd is a pipe */
-	ts->rd->f_flags |= O_NONBLOCK;
+	/* Prevent workers from hanging on IO when fd is a pipe.
+	 * It's technically possible for userspace or concurrent mounts to
+	 * modify this flag concurrently, which will likely result in a
+	 * broken filesystem. However, just having bad flags here should
+	 * not crash the kernel or cause any other sort of bug, so mark this
+	 * particular data race as intentional so that tooling (like KCSAN)
+	 * can allow it and detect further problems.
+	 */
+	data_race(ts->rd->f_flags |= O_NONBLOCK);
 	ts->wr = fget(wfd);
 	if (!ts->wr)
 		goto out_put_rd;
 	if (!(ts->wr->f_mode & FMODE_WRITE))
 		goto out_put_wr;
-	ts->wr->f_flags |= O_NONBLOCK;
+	data_race(ts->wr->f_flags |= O_NONBLOCK);
 
 	client->trans = ts;
 	client->status = Connected;



[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