All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: =?UTF-8?B?Um9iZXJ0IMWad2nEmWNraQ==?= <robert@swiecki.net>
Cc: dhowells@redhat.com, Serge Hallyn <serge.hallyn@canonical.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	"Paul E. McKenney" <paulmck@us.ibm.com>,
	linux-kernel@vger.kernel.org
Subject: Re: Fw: Badness around put_cred()
Date: Fri, 27 Jan 2012 18:13:21 +0000	[thread overview]
Message-ID: <6502.1327688001@redhat.com> (raw)
In-Reply-To: <CAP145pggJUr9NnHNPMF2_i58+axbLT+YYaoetQ13Gwt7cnrvOQ@mail.gmail.com>

Robert Święcki <robert@swiecki.net> wrote:

> I was fuzzing linux kernel for some time, and there seems to be a bug,
> which kicks in relatively quickly (a few hours at most), which ends up
> with warn() or panic() - depending on options compiled in
> (CONFIG_DEBUG_CREDENTIALS, preemption mode). I was looking briefly
> through kernel code, and I think it might be related to the
> include/linux/cred.h::
>
> static inline void put_cred(const struct cred *_cred)
> {
>         struct cred *cred = (struct cred *) _cred;
>
>         validate_creds(cred);
>         if (atomic_dec_and_test(&(cred)->usage))
>                 __put_cred(cred);
> }
>
> which checks whether the usage counter is different than 0, and maybe
> it should be checking whether it is >0.

The creds should get retired when the usage count reaches 0.  It should never
go negative.

> All in all, I don't understand the whole cred/rcu code yet, so just
> dumping the data, in case somebody else can spot the problem quicker.
> The kernel versions are 2.6.39 and 3.2

I can give you a summary of the way the creds work if you need it:

 (1) A process's UIDs, GIDs, groups list, LSM IDs, key subscriptions, etc. are
     its credentials.  These are separated out so they can be overridden more
     easily.

 (2) A process has *two* pointers to its own creds and normally these point to
     the same set of creds.

     (a) The first set of creds (task->real_cred) specifies how this process
     	 appears to other processes and governs what those other processes are
     	 permitted to do to it.  This set is only changed when the process
     	 itself adjusts its creds (such as calling setuid() or exec()).

     (b) The second set of creds (task->cred) governs how this process acts
     	 towards other objects within the system.  These are normally set to
     	 the same as the first set.  However, the kernel may override these to
     	 perform actions in other contexts without affecting how other
     	 processes act upon this one.

 (3) Each process cred pointers holds a ref on the creds it points to.

 (4) A process may only change its own cred pointers and may not change anyone
     else's.

 (5) A process may only change the first cred pointer (2a) if the second cred
     pointer (2b) is currently the same.

 (6) A process may use its own creds without taking any locks whatsoever due to
     point (4).

 (7) A process must observe RCU COW protocol when updating its cred pointers.

 (8) A process may access another process's creds without taking a ref provided
     it holds the RCU read lock.  These creds may be replaced whilst they are
     being examined.  If that is a problem, some other lock must be used as
     well.

 (9) A process may retain another's creds by taking a ref on them under lock,
     but not the RCU read lock as the cred may have had their last reference
     released since the RCU read lock was taken.

(10) Once a new cred struct has been published (ie. made visible to the rest of
     the system) it may not be changed.

(11) Destruction of a cred struct must be deferred until all currently held RCU
     read locks are released.

David

  parent reply	other threads:[~2012-01-27 18:13 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20120126012626.09ca152f.akpm@linux-foundation.org>
     [not found] ` <20120126162820.GA7083@sergelap>
2012-01-26 23:18   ` Fw: Badness around put_cred() Robert Święcki
2012-01-26 23:31     ` Paul E. McKenney
2012-01-27 18:13     ` David Howells [this message]
2012-01-27 18:25     ` David Howells

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=6502.1327688001@redhat.com \
    --to=dhowells@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulmck@us.ibm.com \
    --cc=robert@swiecki.net \
    --cc=serge.hallyn@canonical.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.