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: <ZulMlPFKiiRe3iFd@casper.infradead.org>
Date: Tue, 17 Sep 2024 10:32:04 +0100
From: Matthew Wilcox <willy@...radead.org>
To: Chris Mason <clm@...a.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>,
	Dave Chinner <david@...morbit.com>, Jens Axboe <axboe@...nel.dk>,
	Christian Theune <ct@...ingcircus.io>, linux-mm@...ck.org,
	"linux-xfs@...r.kernel.org" <linux-xfs@...r.kernel.org>,
	linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
	Daniel Dao <dqminh@...udflare.com>, regressions@...ts.linux.dev,
	regressions@...mhuis.info
Subject: Re: Known and unfixed active data loss bug in MM + XFS with large
 folios since Dec 2021 (any kernel from 6.1 upwards)

On Mon, Sep 16, 2024 at 10:47:10AM +0200, Chris Mason wrote:
> I've got a bunch of assertions around incorrect folio->mapping and I'm
> trying to bash on the ENOMEM for readahead case.  There's a GFP_NOWARN
> on those, and our systems do run pretty short on ram, so it feels right
> at least.  We'll see.

I've been running with some variant of this patch the whole way across
the Atlantic, and not hit any problems.  But maybe with the right
workload ...?

There are two things being tested here.  One is whether we have a
cross-linked node (ie a node that's in two trees at the same time).
The other is whether the slab allocator is giving us a node that already
contains non-NULL entries.

If you could throw this on top of your kernel, we might stand a chance
of catching the problem sooner.  If it is one of these problems and not
something weirder.

diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 0b618ec04115..006556605eb3 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -1179,6 +1179,8 @@ struct xa_node {
 
 void xa_dump(const struct xarray *);
 void xa_dump_node(const struct xa_node *);
+void xa_dump_index(unsigned long index, unsigned int shift);
+void xa_dump_entry(const void *entry, unsigned long index, unsigned long shift);
 
 #ifdef XA_DEBUG
 #define XA_BUG_ON(xa, x) do {					\
diff --git a/lib/xarray.c b/lib/xarray.c
index 32d4bac8c94c..6bb35bdca30e 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -6,6 +6,8 @@
  * Author: Matthew Wilcox <willy@...radead.org>
  */
 
+#define XA_DEBUG
+
 #include <linux/bitmap.h>
 #include <linux/export.h>
 #include <linux/list.h>
@@ -206,6 +208,7 @@ static __always_inline void *xas_descend(struct xa_state *xas,
 	unsigned int offset = get_offset(xas->xa_index, node);
 	void *entry = xa_entry(xas->xa, node, offset);
 
+	XA_NODE_BUG_ON(node, node->array != xas->xa);
 	xas->xa_node = node;
 	while (xa_is_sibling(entry)) {
 		offset = xa_to_sibling(entry);
@@ -309,6 +312,7 @@ bool xas_nomem(struct xa_state *xas, gfp_t gfp)
 		return false;
 	xas->xa_alloc->parent = NULL;
 	XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list));
+	XA_NODE_BUG_ON(xas->xa_alloc, memchr_inv(&xas->xa_alloc->slots, 0, sizeof(void *) * XA_CHUNK_SIZE));
 	xas->xa_node = XAS_RESTART;
 	return true;
 }
@@ -345,6 +349,7 @@ static bool __xas_nomem(struct xa_state *xas, gfp_t gfp)
 		return false;
 	xas->xa_alloc->parent = NULL;
 	XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list));
+	XA_NODE_BUG_ON(xas->xa_alloc, memchr_inv(&xas->xa_alloc->slots, 0, sizeof(void *) * XA_CHUNK_SIZE));
 	xas->xa_node = XAS_RESTART;
 	return true;
 }
@@ -388,6 +393,7 @@ static void *xas_alloc(struct xa_state *xas, unsigned int shift)
 	}
 	XA_NODE_BUG_ON(node, shift > BITS_PER_LONG);
 	XA_NODE_BUG_ON(node, !list_empty(&node->private_list));
+	XA_NODE_BUG_ON(node, memchr_inv(&node->slots, 0, sizeof(void *) * XA_CHUNK_SIZE));
 	node->shift = shift;
 	node->count = 0;
 	node->nr_values = 0;

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ