<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-toradex.git/security/keys/key.c, branch v3.4.55</title>
<subtitle>Linux kernel for Apalis and Colibri modules</subtitle>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/'/>
<entry>
<title>Created a function for setting timeouts on keys</title>
<updated>2012-03-01T21:50:31+00:00</updated>
<author>
<name>Bryan Schumaker</name>
<email>bjschuma@netapp.com</email>
</author>
<published>2012-02-24T19:14:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=59e6b9c11341e3b8ac5925427c903d4eae435bd8'/>
<id>59e6b9c11341e3b8ac5925427c903d4eae435bd8</id>
<content type='text'>
The keyctl_set_timeout function isn't exported to other parts of the
kernel, but I want to use it for the NFS idmapper.  I already have the
key, but I wanted a generic way to set the timeout.

Signed-off-by: Bryan Schumaker &lt;bjschuma@netapp.com&gt;
Acked-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Trond Myklebust &lt;Trond.Myklebust@netapp.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The keyctl_set_timeout function isn't exported to other parts of the
kernel, but I want to use it for the NFS idmapper.  I already have the
key, but I wanted a generic way to set the timeout.

Signed-off-by: Bryan Schumaker &lt;bjschuma@netapp.com&gt;
Acked-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Trond Myklebust &lt;Trond.Myklebust@netapp.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>keys: add a "logon" key type</title>
<updated>2012-01-18T04:39:40+00:00</updated>
<author>
<name>Jeff Layton</name>
<email>jlayton@redhat.com</email>
</author>
<published>2012-01-17T21:09:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=9f6ed2ca257fa8650b876377833e6f14e272848b'/>
<id>9f6ed2ca257fa8650b876377833e6f14e272848b</id>
<content type='text'>
For CIFS, we want to be able to store NTLM credentials (aka username
and password) in the keyring. We do not, however want to allow users
to fetch those keys back out of the keyring since that would be a
security risk.

Unfortunately, due to the nuances of key permission bits, it's not
possible to do this. We need to grant search permissions so the kernel
can find these keys, but that also implies permissions to read the
payload.

Resolve this by adding a new key_type. This key type is essentially
the same as key_type_user, but does not define a .read op. This
prevents the payload from ever being visible from userspace. This
key type also vets the description to ensure that it's "qualified"
by checking to ensure that it has a ':' in it that is preceded by
other characters.

Acked-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Jeff Layton &lt;jlayton@redhat.com&gt;
Signed-off-by: Steve French &lt;smfrench@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For CIFS, we want to be able to store NTLM credentials (aka username
and password) in the keyring. We do not, however want to allow users
to fetch those keys back out of the keyring since that would be a
security risk.

Unfortunately, due to the nuances of key permission bits, it's not
possible to do this. We need to grant search permissions so the kernel
can find these keys, but that also implies permissions to read the
payload.

Resolve this by adding a new key_type. This key type is essentially
the same as key_type_user, but does not define a .read op. This
prevents the payload from ever being visible from userspace. This
key type also vets the description to ensure that it's "qualified"
by checking to ensure that it has a ':' in it that is preceded by
other characters.

Acked-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Jeff Layton &lt;jlayton@redhat.com&gt;
Signed-off-by: Steve French &lt;smfrench@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Give key types their own lockdep class for key-&gt;sem</title>
<updated>2011-11-16T22:35:32+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-11-16T11:15:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=7845bc3964756240863ae453ffe4f7ee27ddc954'/>
<id>7845bc3964756240863ae453ffe4f7ee27ddc954</id>
<content type='text'>
Give keys their own lockdep class to differentiate them from each other in case
a key of one type has to refer to a key of another type.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: Mimi Zohar &lt;zohar@us.ibm.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Give keys their own lockdep class to differentiate them from each other in case
a key of one type has to refer to a key of another type.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: Mimi Zohar &lt;zohar@us.ibm.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Correctly destroy key payloads when their keytype is removed</title>
<updated>2011-08-22T23:57:37+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-08-22T13:09:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=0c061b5707ab84ebfe8f18f1c9c3110ae5cd6073'/>
<id>0c061b5707ab84ebfe8f18f1c9c3110ae5cd6073</id>
<content type='text'>
unregister_key_type() has code to mark a key as dead and make it unavailable in
one loop and then destroy all those unavailable key payloads in the next loop.
However, the loop to mark keys dead renders the key undetectable to the second
loop by changing the key type pointer also.

Fix this by the following means:

 (1) The key code has two garbage collectors: one deletes unreferenced keys and
     the other alters keyrings to delete links to old dead, revoked and expired
     keys.  They can end up holding each other up as both want to scan the key
     serial tree under spinlock.  Combine these into a single routine.

 (2) Move the dead key marking, dead link removal and dead key removal into the
     garbage collector as a three phase process running over the three cycles
     of the normal garbage collection procedure.  This is tracked by the
     KEY_GC_REAPING_DEAD_1, _2 and _3 state flags.

     unregister_key_type() then just unlinks the key type from the list, wakes
     up the garbage collector and waits for the third phase to complete.

 (3) Downgrade the key types sem in unregister_key_type() once it has deleted
     the key type from the list so that it doesn't block the keyctl() syscall.

 (4) Dead keys that cannot be simply removed in the third phase have their
     payloads destroyed with the key's semaphore write-locked to prevent
     interference by the keyctl() syscall.  There should be no in-kernel users
     of dead keys of that type by the point of unregistration, though keyctl()
     may be holding a reference.

 (5) Only perform timer recalculation in the GC if the timer actually expired.
     If it didn't, we'll get another cycle when it goes off - and if the key
     that actually triggered it has been removed, it's not a problem.

 (6) Only garbage collect link if the timer expired or if we're doing dead key
     clean up phase 2.

 (7) As only key_garbage_collector() is permitted to use rb_erase() on the key
     serial tree, it doesn't need to revalidate its cursor after dropping the
     spinlock as the node the cursor points to must still exist in the tree.

 (8) Drop the spinlock in the GC if there is contention on it or if we need to
     reschedule.  After dealing with that, get the spinlock again and resume
     scanning.

This has been tested in the following ways:

 (1) Run the keyutils testsuite against it.

 (2) Using the AF_RXRPC and RxKAD modules to test keytype removal:

     Load the rxrpc_s key type:

	# insmod /tmp/af-rxrpc.ko
	# insmod /tmp/rxkad.ko

     Create a key (http://people.redhat.com/~dhowells/rxrpc/listen.c):

	# /tmp/listen &amp;
	[1] 8173

     Find the key:

	# grep rxrpc_s /proc/keys
	091086e1 I--Q--     1 perm 39390000     0     0 rxrpc_s   52:2

     Link it to a session keyring, preferably one with a higher serial number:

	# keyctl link 0x20e36251 @s

     Kill the process (the key should remain as it's linked to another place):

	# fg
	/tmp/listen
	^C

     Remove the key type:

	rmmod rxkad
	rmmod af-rxrpc

     This can be made a more effective test by altering the following part of
     the patch:

	if (unlikely(gc_state &amp; KEY_GC_REAPING_DEAD_2)) {
		/* Make sure everyone revalidates their keys if we marked a
		 * bunch as being dead and make sure all keyring ex-payloads
		 * are destroyed.
		 */
		kdebug("dead sync");
		synchronize_rcu();

     To call synchronize_rcu() in GC phase 1 instead.  That causes that the
     keyring's old payload content to hang around longer until it's RCU
     destroyed - which usually happens after GC phase 3 is complete.  This
     allows the destroy_dead_key branch to be tested.

Reported-by: Benjamin Coddington &lt;bcodding@gmail.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
unregister_key_type() has code to mark a key as dead and make it unavailable in
one loop and then destroy all those unavailable key payloads in the next loop.
However, the loop to mark keys dead renders the key undetectable to the second
loop by changing the key type pointer also.

Fix this by the following means:

 (1) The key code has two garbage collectors: one deletes unreferenced keys and
     the other alters keyrings to delete links to old dead, revoked and expired
     keys.  They can end up holding each other up as both want to scan the key
     serial tree under spinlock.  Combine these into a single routine.

 (2) Move the dead key marking, dead link removal and dead key removal into the
     garbage collector as a three phase process running over the three cycles
     of the normal garbage collection procedure.  This is tracked by the
     KEY_GC_REAPING_DEAD_1, _2 and _3 state flags.

     unregister_key_type() then just unlinks the key type from the list, wakes
     up the garbage collector and waits for the third phase to complete.

 (3) Downgrade the key types sem in unregister_key_type() once it has deleted
     the key type from the list so that it doesn't block the keyctl() syscall.

 (4) Dead keys that cannot be simply removed in the third phase have their
     payloads destroyed with the key's semaphore write-locked to prevent
     interference by the keyctl() syscall.  There should be no in-kernel users
     of dead keys of that type by the point of unregistration, though keyctl()
     may be holding a reference.

 (5) Only perform timer recalculation in the GC if the timer actually expired.
     If it didn't, we'll get another cycle when it goes off - and if the key
     that actually triggered it has been removed, it's not a problem.

 (6) Only garbage collect link if the timer expired or if we're doing dead key
     clean up phase 2.

 (7) As only key_garbage_collector() is permitted to use rb_erase() on the key
     serial tree, it doesn't need to revalidate its cursor after dropping the
     spinlock as the node the cursor points to must still exist in the tree.

 (8) Drop the spinlock in the GC if there is contention on it or if we need to
     reschedule.  After dealing with that, get the spinlock again and resume
     scanning.

This has been tested in the following ways:

 (1) Run the keyutils testsuite against it.

 (2) Using the AF_RXRPC and RxKAD modules to test keytype removal:

     Load the rxrpc_s key type:

	# insmod /tmp/af-rxrpc.ko
	# insmod /tmp/rxkad.ko

     Create a key (http://people.redhat.com/~dhowells/rxrpc/listen.c):

	# /tmp/listen &amp;
	[1] 8173

     Find the key:

	# grep rxrpc_s /proc/keys
	091086e1 I--Q--     1 perm 39390000     0     0 rxrpc_s   52:2

     Link it to a session keyring, preferably one with a higher serial number:

	# keyctl link 0x20e36251 @s

     Kill the process (the key should remain as it's linked to another place):

	# fg
	/tmp/listen
	^C

     Remove the key type:

	rmmod rxkad
	rmmod af-rxrpc

     This can be made a more effective test by altering the following part of
     the patch:

	if (unlikely(gc_state &amp; KEY_GC_REAPING_DEAD_2)) {
		/* Make sure everyone revalidates their keys if we marked a
		 * bunch as being dead and make sure all keyring ex-payloads
		 * are destroyed.
		 */
		kdebug("dead sync");
		synchronize_rcu();

     To call synchronize_rcu() in GC phase 1 instead.  That causes that the
     keyring's old payload content to hang around longer until it's RCU
     destroyed - which usually happens after GC phase 3 is complete.  This
     allows the destroy_dead_key branch to be tested.

Reported-by: Benjamin Coddington &lt;bcodding@gmail.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Make the key reaper non-reentrant</title>
<updated>2011-08-22T23:57:36+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-08-22T13:09:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=b072e9bc2fe9aeff4e104e80e479160349f474a9'/>
<id>b072e9bc2fe9aeff4e104e80e479160349f474a9</id>
<content type='text'>
Make the key reaper non-reentrant by sticking it on the appropriate system work
queue when we queue it.  This will allow it to have global state and drop
locks.  It should probably be non-reentrant already as it may spend a long time
holding the key serial spinlock, and so multiple entrants can spend long
periods of time just sitting there spinning, waiting to get the lock.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Make the key reaper non-reentrant by sticking it on the appropriate system work
queue when we queue it.  This will allow it to have global state and drop
locks.  It should probably be non-reentrant already as it may spend a long time
holding the key serial spinlock, and so multiple entrants can spend long
periods of time just sitting there spinning, waiting to get the lock.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Move the unreferenced key reaper to the keys garbage collector file</title>
<updated>2011-08-22T23:57:36+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-08-22T13:09:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=8bc16deabce7649e480e94b648c88d4e90c34352'/>
<id>8bc16deabce7649e480e94b648c88d4e90c34352</id>
<content type='text'>
Move the unreferenced key reaper function to the keys garbage collector file
as that's a more appropriate place with the dead key link reaper.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Move the unreferenced key reaper function to the keys garbage collector file
as that's a more appropriate place with the dead key link reaper.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Add a new keyctl op to reject a key with a specified error code</title>
<updated>2011-03-08T00:17:18+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-03-07T15:06:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=fdd1b94581782a2ddf9124414e5b7a5f48ce2f9c'/>
<id>fdd1b94581782a2ddf9124414e5b7a5f48ce2f9c</id>
<content type='text'>
Add a new keyctl op to reject a key with a specified error code.  This works
much the same as negating a key, and so keyctl_negate_key() is made a special
case of keyctl_reject_key().  The difference is that keyctl_negate_key()
selects ENOKEY as the error to be reported.

Typically the key would be rejected with EKEYEXPIRED, EKEYREVOKED or
EKEYREJECTED, but this is not mandatory.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add a new keyctl op to reject a key with a specified error code.  This works
much the same as negating a key, and so keyctl_negate_key() is made a special
case of keyctl_reject_key().  The difference is that keyctl_negate_key()
selects ENOKEY as the error to be reported.

Typically the key would be rejected with EKEYEXPIRED, EKEYREVOKED or
EKEYREJECTED, but this is not mandatory.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Add a key type op to permit the key description to be vetted</title>
<updated>2011-03-08T00:17:15+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-03-07T15:05:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=b9fffa3877a3ebbe0a5ad5a247358e2f7df15b24'/>
<id>b9fffa3877a3ebbe0a5ad5a247358e2f7df15b24</id>
<content type='text'>
Add a key type operation to permit the key type to vet the description of a new
key that key_alloc() is about to allocate.  The operation may reject the
description if it wishes with an error of its choosing.  If it does this, the
key will not be allocated.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Mimi Zohar &lt;zohar@us.ibm.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add a key type operation to permit the key type to vet the description of a new
key that key_alloc() is about to allocate.  The operation may reject the
description if it wishes with an error of its choosing.  If it does this, the
key will not be allocated.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Mimi Zohar &lt;zohar@us.ibm.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Fix __key_link_end() quota fixup on error</title>
<updated>2011-01-25T22:58:20+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-01-25T16:34:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=ceb73c12047b8d543570b23353e7848eb7c540a1'/>
<id>ceb73c12047b8d543570b23353e7848eb7c540a1</id>
<content type='text'>
Fix __key_link_end()'s attempt to fix up the quota if an error occurs.

There are two erroneous cases: Firstly, we always decrease the quota if
the preallocated replacement keyring needs cleaning up, irrespective of
whether or not we should (we may have replaced a pointer rather than
adding another pointer).

Secondly, we never clean up the quota if we added a pointer without the
keyring storage being extended (we allocate multiple pointers at a time,
even if we're not going to use them all immediately).

We handle this by setting the bottom bit of the preallocation pointer in
__key_link_begin() to indicate that the quota needs fixing up, which is
then passed to __key_link() (which clears the whole thing) and
__key_link_end().

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fix __key_link_end()'s attempt to fix up the quota if an error occurs.

There are two erroneous cases: Firstly, we always decrease the quota if
the preallocated replacement keyring needs cleaning up, irrespective of
whether or not we should (we may have replaced a pointer rather than
adding another pointer).

Secondly, we never clean up the quota if we added a pointer without the
keyring storage being extended (we allocate multiple pointers at a time,
even if we're not going to use them all immediately).

We handle this by setting the bottom bit of the preallocation pointer in
__key_link_begin() to indicate that the quota needs fixing up, which is
then passed to __key_link() (which clears the whole thing) and
__key_link_end().

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KEYS: Fix up comments in key management code</title>
<updated>2011-01-21T22:59:30+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2011-01-20T16:38:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=973c9f4f49ca96a53bcf6384c4c59ccd26c33906'/>
<id>973c9f4f49ca96a53bcf6384c4c59ccd26c33906</id>
<content type='text'>
Fix up comments in the key management code.  No functional changes.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fix up comments in the key management code.  No functional changes.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
