Linux filesystem development
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: NeilBrown <neil@brown.name>
Cc: Kees Cook <kees@kernel.org>,
	Joel Granados <joel.granados@kernel.org>,
	linux-fsdevel@vger.kernel.org,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3?] proc_sysctl: remove rcu_dereference() for accessing ->sysctl
Date: Mon, 16 Jun 2025 00:57:14 +0100	[thread overview]
Message-ID: <20250615235714.GG1880847@ZenIV> (raw)
In-Reply-To: <175002843966.608730.14640390628578526912@noble.neil.brown.name>

On Mon, Jun 16, 2025 at 09:00:39AM +1000, NeilBrown wrote:
> 
> The rcu_dereference() call in proc_sys_compare() is problematic as
> ->d_compare is not guaranteed to be called with rcu_read_lock() held and
> rcu_dereference() can cause a warning when used without that lock.
> 
> Specifically d_alloc_parallel() will call ->d_compare() without
> rcu_read_lock(), but with ->d_lock to ensure stability.  In this case
> ->d_inode is usually NULL so the rcu_dereference() will normally not be
> reached, but it is possible that ->d_inode was set while waiting for
> ->d_lock which could lead to the warning.

Huh?

There are two call sites of d_same_name() in d_alloc_parallel() - one
in the loop (under rcu_read_lock()) and another after the thing we
are comparing has ceased to be in-lookup.  The latter is under ->d_lock,
stabilizing everything (and it really can't run into NULL ->d_inode
for /proc/sys/ stuff).

->d_compare() instances are guaranteed dentry->d_lock or rcu_read_lock();
in the latter case we'll either recheck or validate on previously sampled
->d_seq.  And the second call in d_alloc_parallel() is just that - recheck
under ->d_lock.

Just use rcu_dereference_check(...., spin_is_locked(&dentry->d_lock)) and
be done with that...

The part where we have a somewhat wrong behaviour is not the second call
in d_alloc_parallel() - it's the first one.  Something like this

static int proc_sys_compare(const struct dentry *dentry,
		unsigned int len, const char *str, const struct qstr *name)
{
	struct ctl_table_header *head;
	struct inode *inode;

	if (name->len != len)
		return 1;
	if (memcmp(name->name, str, len))
		return 1;

	// false positive is fine here - we'll recheck anyway
	if (d_in_lookup(dentry))
		return 0;

	inode = d_inode_rcu(dentry);
	// we just might have run into dentry in the middle of __dentry_kill()
	if (!inode)
		return 1;
	head = rcu_dereference_check(PROC_I(inode)->sysctl,
				     spin_is_locked(&dentry->d_lock));
	return !head || !sysctl_is_seen(head);
}

  reply	other threads:[~2025-06-15 23:57 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-15 23:00 [PATCH v3?] proc_sysctl: remove rcu_dereference() for accessing ->sysctl NeilBrown
2025-06-15 23:57 ` Al Viro [this message]
2025-06-16  2:49   ` NeilBrown
2025-07-03 23:43     ` Al Viro
2025-07-04  1:02       ` Al Viro
2025-07-04  1:39         ` NeilBrown
2025-07-04  2:19           ` Al Viro
2025-07-04  1:39       ` NeilBrown
2025-07-04  2:03         ` Al Viro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250615235714.GG1880847@ZenIV \
    --to=viro@zeniv.linux.org.uk \
    --cc=joel.granados@kernel.org \
    --cc=kees@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=neil@brown.name \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox