public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alice Ryhl <aliceryhl@google.com>
To: Paul Moore <paul@paul-moore.com>
Cc: Serge Hallyn <sergeh@kernel.org>,
	linux-security-module@vger.kernel.org,
	 linux-kernel@vger.kernel.org
Subject: Re: [PATCH] cred: clarify usage of get_cred_rcu()
Date: Fri, 27 Feb 2026 10:04:53 +0000	[thread overview]
Message-ID: <aaFsRbMZl2OIlSCg@google.com> (raw)
In-Reply-To: <CAHC9VhTwJbuXrdUFxWLVWfgk45hLScPgaC9Xb+R2NH6NGdaMZQ@mail.gmail.com>

On Thu, Feb 26, 2026 at 09:18:29PM -0500, Paul Moore wrote:
> On Fri, Feb 20, 2026 at 4:19 AM Alice Ryhl <aliceryhl@google.com> wrote:
> >
> > After being confused by looking at get_cred() and get_cred_rcu(), I
> > figured out what's going on. Thus, add some comments to clarify how
> > get_cred_rcu() works for the benefit of others looking in the future.
> >
> > Note that in principle we could add an assertion that non_rcu is zero in
> > the failure path of atomic_long_inc_not_zero().
> 
> That would be interesting to add a WARN_ON() there and see what
> happens.  Hopefully nothing, but one never knows ;)  Have you tried
> this?

I tried just now. I put it on an Android phone, and it did not seem to
be triggered after a few minute of usage.

I can send a patch adding it if you would like?

> > Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> > ---
> >  include/linux/cred.h | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> 
> ...
> 
> > +/*
> > + * get_cred_rcu - Get a reference on a set of credentials under rcu
> 
> I agree this is a bit pedantic, but it looks like the bulk of the file
> capitalizes RCU and technically that is correct as it is an acronym.

Will do.

> > + * @cred: The credentials to reference
> > + *
> > + * Get a reference on the specified set of credentials, or %NULL if the last
> > + * refcount has already been put.
> > + *
> > + * This is used to obtain a reference under an rcu read lock.
> 
> I would suggest a different description:
> 
> "Get a reference to the specified set of credentials and return a
> pointer to the cred struct, or %NULL if it is not possible to obtain a
> new reference.  After successfully taking a new reference to the
> specified credentials, the cred struct will be marked for free'ing via
> RCU."

I actually think it's confusing to include

	After successfully taking a new reference to the specified
	credentials, the cred struct will be marked for free'ing via
	RCU.

in the documentation, because it makes it sounds like this method has
the _rcu() suffix because it marks the struct for free'ing via RCU. But
that is not the case. After all, get_cred() also marks it for free'ing
via RCU.

It has the _rcu() suffix because - if the cred struct is *already*
marked for free'ing via RCU, then you are allowed to do this:

	rcu_read_lock();
	cred = get_cred_rcu(&foo->my_cred);
	rcu_read_unlock();

even if another thread might put foo->my_cred in parallel with the above
piece of code.

> > + */
> >  static inline const struct cred *get_cred_rcu(const struct cred *cred)
> >  {
> >         struct cred *nonconst_cred = (struct cred *) cred;
> >         if (!cred)
> >                 return NULL;
> >         if (!atomic_long_inc_not_zero(&nonconst_cred->usage))
> >                 return NULL;
> > +       /*
> > +        * If non_rcu is not already zero, then this call to get_cred_rcu() is
> > +        * probably wrong because if 'usage' goes to zero prior to this call,
> > +        * then get_cred_rcu() assumes it is freed with rcu.
> > +        *
> > +        * However, an exception to this is using get_cred_rcu() in cases where
> > +        * get_cred() would have been okay. To support that case, we do not
> > +        * check non_rcu and set it to zero regardless.
> > +        */
> 
> This is surely a matter of perspective, but the above seems a bit
> wordy, and doesn't address what I believe is the important part:
> setting non_rcu to zero means this credential will be freed
> asynchronously via RCU.  Both get_cred_rcu() and get_cred() set
> non_rcu to 0/false ... although get_cred() doesn't do the non-zero
> check before bumping the refcount.

I think that would be a good comment to add to get_cred(), but in the
case of get_cred_rcu(), it really should already be set to zero, because
otherwise

	rcu_read_lock();
	cred = get_cred_rcu(&foo->my_cred);
	rcu_read_unlock();

is illegal.

> I suppose we could consider adding the zero check in the get_cred()
> case, but even if we ignore the KCSAN barrier, it looks like the arch
> support for the inc_not_zero() case isn't nearly as good, likely
> resulting in more code to execute.

I don't think that's necessary. If you use get_cred() in a scenario
where it might be zero, you have a bug.

Alice

  reply	other threads:[~2026-02-27 10:04 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-20  9:19 [PATCH] cred: clarify usage of get_cred_rcu() Alice Ryhl
2026-02-27  2:18 ` Paul Moore
2026-02-27 10:04   ` Alice Ryhl [this message]
2026-02-27 20:49     ` Paul Moore

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=aaFsRbMZl2OIlSCg@google.com \
    --to=aliceryhl@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=sergeh@kernel.org \
    /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