<feed xmlns='http://www.w3.org/2005/Atom'>
<title>user/sven/linux.git/security/keys/user_defined.c, branch v4.9.296</title>
<subtitle>Linux Kernel
</subtitle>
<id>https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v4.9.296</id>
<link rel='self' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v4.9.296'/>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/'/>
<updated>2017-10-27T08:38:11Z</updated>
<entry>
<title>KEYS: Fix race between updating and finding a negative key</title>
<updated>2017-10-27T08:38:11Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2017-10-04T15:43:25Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=63c8e452554962f88c0952212c8a4202469d4914'/>
<id>urn:sha1:63c8e452554962f88c0952212c8a4202469d4914</id>
<content type='text'>
commit 363b02dab09b3226f3bd1420dad9c72b79a42a76 upstream.

Consolidate KEY_FLAG_INSTANTIATED, KEY_FLAG_NEGATIVE and the rejection
error into one field such that:

 (1) The instantiation state can be modified/read atomically.

 (2) The error can be accessed atomically with the state.

 (3) The error isn't stored unioned with the payload pointers.

This deals with the problem that the state is spread over three different
objects (two bits and a separate variable) and reading or updating them
atomically isn't practical, given that not only can uninstantiated keys
change into instantiated or rejected keys, but rejected keys can also turn
into instantiated keys - and someone accessing the key might not be using
any locking.

The main side effect of this problem is that what was held in the payload
may change, depending on the state.  For instance, you might observe the
key to be in the rejected state.  You then read the cached error, but if
the key semaphore wasn't locked, the key might've become instantiated
between the two reads - and you might now have something in hand that isn't
actually an error code.

The state is now KEY_IS_UNINSTANTIATED, KEY_IS_POSITIVE or a negative error
code if the key is negatively instantiated.  The key_is_instantiated()
function is replaced with key_is_positive() to avoid confusion as negative
keys are also 'instantiated'.

Additionally, barriering is included:

 (1) Order payload-set before state-set during instantiation.

 (2) Order state-read before payload-read when using the key.

Further separate barriering is necessary if RCU is being used to access the
payload content after reading the payload pointers.

Fixes: 146aa8b1453b ("KEYS: Merge the type-specific data with the payload data")
Reported-by: Eric Biggers &lt;ebiggers@google.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Eric Biggers &lt;ebiggers@google.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>KEYS: user_update should use copy of payload made during preparsing</title>
<updated>2016-04-12T18:54:58Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2016-04-12T18:54:58Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=898de7d0f298e53568891f0ec3547b14fe8bb5d5'/>
<id>urn:sha1:898de7d0f298e53568891f0ec3547b14fe8bb5d5</id>
<content type='text'>
The payload preparsing routine for user keys makes a copy of the payload
provided by the caller and stashes it in the key_preparsed_payload struct for
-&gt;instantiate() or -&gt;update() to use.  However, -&gt;update() takes another copy
of this to attach to the keyring.  -&gt;update() should be using this directly
and clearing the pointer in the preparse data.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
</content>
</entry>
<entry>
<title>KEYS: Fix handling of stored error in a negatively instantiated user key</title>
<updated>2015-11-25T03:19:47Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2015-11-24T21:36:31Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=096fe9eaea40a17e125569f9e657e34cdb6d73bd'/>
<id>urn:sha1:096fe9eaea40a17e125569f9e657e34cdb6d73bd</id>
<content type='text'>
If a user key gets negatively instantiated, an error code is cached in the
payload area.  A negatively instantiated key may be then be positively
instantiated by updating it with valid data.  However, the -&gt;update key
type method must be aware that the error code may be there.

The following may be used to trigger the bug in the user key type:

    keyctl request2 user user "" @u
    keyctl add user user "a" @u

which manifests itself as:

	BUG: unable to handle kernel paging request at 00000000ffffff8a
	IP: [&lt;ffffffff810a376f&gt;] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
	PGD 7cc30067 PUD 0
	Oops: 0002 [#1] SMP
	Modules linked in:
	CPU: 3 PID: 2644 Comm: a.out Not tainted 4.3.0+ #49
	Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
	task: ffff88003ddea700 ti: ffff88003dd88000 task.ti: ffff88003dd88000
	RIP: 0010:[&lt;ffffffff810a376f&gt;]  [&lt;ffffffff810a376f&gt;] __call_rcu.constprop.76+0x1f/0x280
	 [&lt;ffffffff810a376f&gt;] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
	RSP: 0018:ffff88003dd8bdb0  EFLAGS: 00010246
	RAX: 00000000ffffff82 RBX: 0000000000000000 RCX: 0000000000000001
	RDX: ffffffff81e3fe40 RSI: 0000000000000000 RDI: 00000000ffffff82
	RBP: ffff88003dd8bde0 R08: ffff88007d2d2da0 R09: 0000000000000000
	R10: 0000000000000000 R11: ffff88003e8073c0 R12: 00000000ffffff82
	R13: ffff88003dd8be68 R14: ffff88007d027600 R15: ffff88003ddea700
	FS:  0000000000b92880(0063) GS:ffff88007fd00000(0000) knlGS:0000000000000000
	CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
	CR2: 00000000ffffff8a CR3: 000000007cc5f000 CR4: 00000000000006e0
	Stack:
	 ffff88003dd8bdf0 ffffffff81160a8a 0000000000000000 00000000ffffff82
	 ffff88003dd8be68 ffff88007d027600 ffff88003dd8bdf0 ffffffff810a39e5
	 ffff88003dd8be20 ffffffff812a31ab ffff88007d027600 ffff88007d027620
	Call Trace:
	 [&lt;ffffffff810a39e5&gt;] kfree_call_rcu+0x15/0x20 kernel/rcu/tree.c:3136
	 [&lt;ffffffff812a31ab&gt;] user_update+0x8b/0xb0 security/keys/user_defined.c:129
	 [&lt;     inline     &gt;] __key_update security/keys/key.c:730
	 [&lt;ffffffff8129e5c1&gt;] key_create_or_update+0x291/0x440 security/keys/key.c:908
	 [&lt;     inline     &gt;] SYSC_add_key security/keys/keyctl.c:125
	 [&lt;ffffffff8129fc21&gt;] SyS_add_key+0x101/0x1e0 security/keys/keyctl.c:60
	 [&lt;ffffffff8185f617&gt;] entry_SYSCALL_64_fastpath+0x12/0x6a arch/x86/entry/entry_64.S:185

Note the error code (-ENOKEY) in EDX.

A similar bug can be tripped by:

    keyctl request2 trusted user "" @u
    keyctl add trusted user "a" @u

This should also affect encrypted keys - but that has to be correctly
parameterised or it will fail with EINVAL before getting to the bit that
will crashes.

Reported-by: Dmitry Vyukov &lt;dvyukov@google.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: Mimi Zohar &lt;zohar@linux.vnet.ibm.com&gt;
Signed-off-by: James Morris &lt;james.l.morris@oracle.com&gt;
</content>
</entry>
<entry>
<title>KEYS: Merge the type-specific data with the payload data</title>
<updated>2015-10-21T14:18:36Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2015-10-21T13:04:48Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=146aa8b1453bd8f1ff2304ffb71b4ee0eb9acdcc'/>
<id>urn:sha1:146aa8b1453bd8f1ff2304ffb71b4ee0eb9acdcc</id>
<content type='text'>
Merge the type-specific data with the payload data into one four-word chunk
as it seems pointless to keep them separate.

Use user_key_payload() for accessing the payloads of overloaded
user-defined keys.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
cc: linux-cifs@vger.kernel.org
cc: ecryptfs@vger.kernel.org
cc: linux-ext4@vger.kernel.org
cc: linux-f2fs-devel@lists.sourceforge.net
cc: linux-nfs@vger.kernel.org
cc: ceph-devel@vger.kernel.org
cc: linux-ima-devel@lists.sourceforge.net
</content>
</entry>
<entry>
<title>KEYS: Remove key_type::match in favour of overriding default by match_preparse</title>
<updated>2014-09-16T16:36:06Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2014-09-16T16:36:06Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=c06cfb08b88dfbe13be44a69ae2fdc3a7c902d81'/>
<id>urn:sha1:c06cfb08b88dfbe13be44a69ae2fdc3a7c902d81</id>
<content type='text'>
A previous patch added a -&gt;match_preparse() method to the key type.  This is
allowed to override the function called by the iteration algorithm.
Therefore, we can just set a default that simply checks for an exact match of
the key description with the original criterion data and allow match_preparse
to override it as needed.

The key_type::match op is then redundant and can be removed, as can the
user_match() function.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: Vivek Goyal &lt;vgoyal@redhat.com&gt;
</content>
</entry>
<entry>
<title>KEYS: Remove key_type::def_lookup_type</title>
<updated>2014-09-16T16:36:04Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2014-09-16T16:36:04Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=614d8c39014c185aa0f7254f0a470cc33fc1b284'/>
<id>urn:sha1:614d8c39014c185aa0f7254f0a470cc33fc1b284</id>
<content type='text'>
Remove key_type::def_lookup_type as it's no longer used.  The information now
defaults to KEYRING_SEARCH_LOOKUP_DIRECT but may be overridden by
type-&gt;match_preparse().

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: Vivek Goyal &lt;vgoyal@redhat.com&gt;
</content>
</entry>
<entry>
<title>KEYS: Preparse match data</title>
<updated>2014-09-16T16:36:02Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2014-09-16T16:36:02Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=462919591a1791e76042dc5c1e0148715df59beb'/>
<id>urn:sha1:462919591a1791e76042dc5c1e0148715df59beb</id>
<content type='text'>
Preparse the match data.  This provides several advantages:

 (1) The preparser can reject invalid criteria up front.

 (2) The preparser can convert the criteria to binary data if necessary (the
     asymmetric key type really wants to do binary comparison of the key IDs).

 (3) The preparser can set the type of search to be performed.  This means
     that it's not then a one-off setting in the key type.

 (4) The preparser can set an appropriate comparator function.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: Vivek Goyal &lt;vgoyal@redhat.com&gt;
</content>
</entry>
<entry>
<title>KEYS: user: Use key preparsing</title>
<updated>2014-07-22T20:46:17Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2014-07-18T17:56:35Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=f9167789df53f22af771fb6690a3d36aa21d74c5'/>
<id>urn:sha1:f9167789df53f22af771fb6690a3d36aa21d74c5</id>
<content type='text'>
Make use of key preparsing in user-defined and logon keys so that quota size
determination can take place prior to keyring locking when a key is being
added.

Also the idmapper key types need to change to match as they use the
user-defined key type routines.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: Steve Dickson &lt;steved@redhat.com&gt;
Acked-by: Jeff Layton &lt;jlayton@primarydata.com&gt;
</content>
</entry>
<entry>
<title>KEYS: Introduce a search context structure</title>
<updated>2013-09-24T09:35:15Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2013-09-24T09:35:15Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=4bdf0bc300314141e5475e145acb8b5ad846f00d'/>
<id>urn:sha1:4bdf0bc300314141e5475e145acb8b5ad846f00d</id>
<content type='text'>
Search functions pass around a bunch of arguments, each of which gets copied
with each call.  Introduce a search context structure to hold these.

Whilst we're at it, create a search flag that indicates whether the search
should be directly to the description or whether it should iterate through all
keys looking for a non-description match.

This will be useful when keyrings use a generic data struct with generic
routines to manage their content as the search terms can just be passed
through to the iterator callback function.

Also, for future use, the data to be supplied to the match function is
separated from the description pointer in the search context.  This makes it
clear which is being supplied.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
</content>
</entry>
<entry>
<title>KEYS: Add payload preparsing opportunity prior to key instantiate or update</title>
<updated>2012-10-08T03:19:48Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2012-09-13T12:06:29Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=cf7f601c067994f371ba77721d1e45fce61a4569'/>
<id>urn:sha1:cf7f601c067994f371ba77721d1e45fce61a4569</id>
<content type='text'>
Give the key type the opportunity to preparse the payload prior to the
instantiation and update routines being called.  This is done with the
provision of two new key type operations:

	int (*preparse)(struct key_preparsed_payload *prep);
	void (*free_preparse)(struct key_preparsed_payload *prep);

If the first operation is present, then it is called before key creation (in
the add/update case) or before the key semaphore is taken (in the update and
instantiate cases).  The second operation is called to clean up if the first
was called.

preparse() is given the opportunity to fill in the following structure:

	struct key_preparsed_payload {
		char		*description;
		void		*type_data[2];
		void		*payload;
		const void	*data;
		size_t		datalen;
		size_t		quotalen;
	};

Before the preparser is called, the first three fields will have been cleared,
the payload pointer and size will be stored in data and datalen and the default
quota size from the key_type struct will be stored into quotalen.

The preparser may parse the payload in any way it likes and may store data in
the type_data[] and payload fields for use by the instantiate() and update()
ops.

The preparser may also propose a description for the key by attaching it as a
string to the description field.  This can be used by passing a NULL or ""
description to the add_key() system call or the key_create_or_update()
function.  This cannot work with request_key() as that required the description
to tell the upcall about the key to be created.

This, for example permits keys that store PGP public keys to generate their own
name from the user ID and public key fingerprint in the key.

The instantiate() and update() operations are then modified to look like this:

	int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
	int (*update)(struct key *key, struct key_preparsed_payload *prep);

and the new payload data is passed in *prep, whether or not it was preparsed.

Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
</content>
</entry>
</feed>
