lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251204024748.3052502-4-zhangshida@kylinos.cn>
Date: Thu,  4 Dec 2025 10:47:48 +0800
From: zhangshida <starzhangzsd@...il.com>
To: Johannes.Thumshirn@....com,
	hch@...radead.org,
	agruenba@...hat.com,
	ming.lei@...hat.com,
	hsiangkao@...ux.alibaba.com,
	csander@...estorage.com,
	colyli@...as.com
Cc: linux-block@...r.kernel.org,
	linux-bcache@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	zhangshida@...inos.cn,
	starzhangzsd@...il.com,
	Christoph Hellwig <hch@....de>
Subject: [PATCH v5 3/3] block: prevent race condition on bi_status in __bio_chain_endio

From: Shida Zhang <zhangshida@...inos.cn>

Andreas point out that multiple completions can race setting
bi_status.

If __bio_chain_endio() is called concurrently from multiple threads
accessing the same parent bio, it should use WRITE_ONCE()/READ_ONCE()
to access parent->bi_status and avoid data races.

On x86 and ARM, these macros compile to the same instruction as a
normal write, but they may be required on other architectures to
prevent tearing, and to ensure the compiler does not add or remove
memory accesses under the assumption that the values are not accessed
concurrently.

Adopting a cmpxchg approach, as used in other code paths, resolves all
these issues, as suggested by Christoph.

Suggested-by: Andreas Gruenbacher <agruenba@...hat.com>
Suggested-by: Christoph Hellwig <hch@...radead.org>
Suggested-by: Caleb Sander Mateos <csander@...estorage.com>
Reviewed-by: Christoph Hellwig <hch@....de>
Signed-off-by: Shida Zhang <zhangshida@...inos.cn>
---
 block/bio.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index cfb751dfcf5..51b57f9d8bd 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -314,8 +314,9 @@ static struct bio *__bio_chain_endio(struct bio *bio)
 {
 	struct bio *parent = bio->bi_private;
 
-	if (bio->bi_status && !parent->bi_status)
-		parent->bi_status = bio->bi_status;
+	if (bio->bi_status)
+		cmpxchg(&parent->bi_status, 0, bio->bi_status);
+
 	bio_put(bio);
 	return parent;
 }
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ