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]
Date: Tue, 20 Feb 2024 10:56:53 +0100
From: Christian Brauner <brauner@...nel.org>
To: Chuck Lever <cel@...nel.org>
Cc: viro@...iv.linux.org.uk, jack@...e.cz, hughd@...gle.com, 
	akpm@...ux-foundation.org, Liam.Howlett@...cle.com, oliver.sang@...el.com, 
	feng.tang@...el.com, linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org, 
	maple-tree@...ts.infradead.org, linux-mm@...ck.org, lkp@...el.com
Subject: Re: [PATCH v2 1/6] libfs: Re-arrange locking in offset_iterate_dir()

On Sat, Feb 17, 2024 at 03:23:40PM -0500, Chuck Lever wrote:
> From: Chuck Lever <chuck.lever@...cle.com>
> 
> Liam and Matthew say that once the RCU read lock is released,
> xa_state is not safe to re-use for the next xas_find() call. But the
> RCU read lock must be released on each loop iteration so that
> dput(), which might_sleep(), can be called safely.

Fwiw, functions like this:

static struct dentry *offset_find_next(struct xa_state *xas)
{
        struct dentry *child, *found = NULL;

        rcu_read_lock();
        child = xas_next_entry(xas, U32_MAX);
        if (!child)
                goto out;
        spin_lock(&child->d_lock);
        if (simple_positive(child))
                found = dget_dlock(child);
        spin_unlock(&child->d_lock);
out:
        rcu_read_unlock();
        return found;
}

should use the new guard feature going forward imho. IOW, in the future such
helpers should be written as:

static struct dentry *offset_find_next(struct xa_state *xas)
{
        struct dentry *child, *found = NULL;

	guard(rcu)();
        child = xas_next_entry(xas, U32_MAX);
        if (!child)
		return NULL;
        spin_lock(&child->d_lock);
        if (simple_positive(child))
                found = dget_dlock(child);
        spin_unlock(&child->d_lock);
        return found;
}

which allows you to eliminate the goto and to have the guarantee that the rcu
lock is released when you return. This also works for other locks btw.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ