]> www.infradead.org Git - users/willy/xarray.git/commitdiff
XArray: Prevent node leaks in xas_alloc()
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Mon, 23 Sep 2024 18:33:40 +0000 (14:33 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Mon, 23 Sep 2024 18:33:40 +0000 (14:33 -0400)
In the following situation, we can leak nodes:

do {
xas_split_alloc();
xas_lock();
/* Discover that xas_split() does not need to be called */
xas_store();
xas_unlock();
} while (xas_nomem());

The xas_store() is expecting to be using a node allocated by xas_alloc(),
but will use a node allocated by xas_split_alloc() instead.  That
will cause us to leak the remaining nodes which are chained through
node->parent.  Fix this by only popping the top node off the xa_alloc
list instead of removing all the nodes.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
lib/xarray.c

index 32d4bac8c94ca13e11f350c6bcfcacc2040d0359..2da34b84ac46623153983a889420774c292f49d7 100644 (file)
@@ -366,7 +366,7 @@ static void *xas_alloc(struct xa_state *xas, unsigned int shift)
                return NULL;
 
        if (node) {
-               xas->xa_alloc = NULL;
+               xas->xa_alloc = rcu_dereference_raw(node->parent);
        } else {
                gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN;