KEYS: user_update should use copy of payload made during preparsing

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
->instantiate() or ->update() to use.  However, ->update() takes another copy
of this to attach to the keyring.  ->update() should be using this directly
and clearing the pointer in the preparse data.

Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
David Howells 2016-04-12 19:54:58 +01:00
parent 93da17b185
commit 898de7d0f2

View File

@ -96,45 +96,25 @@ EXPORT_SYMBOL_GPL(user_free_preparse);
*/
int user_update(struct key *key, struct key_preparsed_payload *prep)
{
struct user_key_payload *upayload, *zap;
size_t datalen = prep->datalen;
struct user_key_payload *zap = NULL;
int ret;
ret = -EINVAL;
if (datalen <= 0 || datalen > 32767 || !prep->data)
goto error;
/* construct a replacement payload */
ret = -ENOMEM;
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
if (!upayload)
goto error;
upayload->datalen = datalen;
memcpy(upayload->data, prep->data, datalen);
/* check the quota and attach the new data */
zap = upayload;
ret = key_payload_reserve(key, prep->datalen);
if (ret < 0)
return ret;
ret = key_payload_reserve(key, datalen);
if (ret == 0) {
/* attach the new data, displacing the old */
if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
zap = key->payload.data[0];
else
zap = NULL;
rcu_assign_keypointer(key, upayload);
key->expiry = 0;
}
/* attach the new data, displacing the old */
key->expiry = prep->expiry;
if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
zap = rcu_dereference_key(key);
rcu_assign_keypointer(key, prep->payload.data[0]);
prep->payload.data[0] = NULL;
if (zap)
kfree_rcu(zap, rcu);
error:
return ret;
}
EXPORT_SYMBOL_GPL(user_update);
/*