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]
Message-ID: <6502.1327688001@redhat.com>
Date:	Fri, 27 Jan 2012 18:13:21 +0000
From:	David Howells <dhowells@...hat.com>
To:	=?UTF-8?B?Um9iZXJ0IMWad2nEmWNraQ==?= 
	<robert@...ecki.net>
Cc:	dhowells@...hat.com, Serge Hallyn <serge.hallyn@...onical.com>,
	Andrew Morton <akpm@...ux-foundation.org>,
	"Paul E. McKenney" <paulmck@...ibm.com>,
	linux-kernel@...r.kernel.org
Subject: Re: Fw: Badness around put_cred()

Robert Święcki <robert@...ecki.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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ