Skip to content

Commit 898de7d

Browse files
committed
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>
1 parent 93da17b commit 898de7d

File tree

1 file changed

+11
-31
lines changed

1 file changed

+11
-31
lines changed

security/keys/user_defined.c

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -96,45 +96,25 @@ EXPORT_SYMBOL_GPL(user_free_preparse);
9696
*/
9797
int user_update(struct key *key, struct key_preparsed_payload *prep)
9898
{
99-
struct user_key_payload *upayload, *zap;
100-
size_t datalen = prep->datalen;
99+
struct user_key_payload *zap = NULL;
101100
int ret;
102101

103-
ret = -EINVAL;
104-
if (datalen <= 0 || datalen > 32767 || !prep->data)
105-
goto error;
106-
107-
/* construct a replacement payload */
108-
ret = -ENOMEM;
109-
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
110-
if (!upayload)
111-
goto error;
112-
113-
upayload->datalen = datalen;
114-
memcpy(upayload->data, prep->data, datalen);
115-
116102
/* check the quota and attach the new data */
117-
zap = upayload;
118-
119-
ret = key_payload_reserve(key, datalen);
120-
121-
if (ret == 0) {
122-
/* attach the new data, displacing the old */
123-
if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
124-
zap = key->payload.data[0];
125-
else
126-
zap = NULL;
127-
rcu_assign_keypointer(key, upayload);
128-
key->expiry = 0;
129-
}
103+
ret = key_payload_reserve(key, prep->datalen);
104+
if (ret < 0)
105+
return ret;
106+
107+
/* attach the new data, displacing the old */
108+
key->expiry = prep->expiry;
109+
if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
110+
zap = rcu_dereference_key(key);
111+
rcu_assign_keypointer(key, prep->payload.data[0]);
112+
prep->payload.data[0] = NULL;
130113

131114
if (zap)
132115
kfree_rcu(zap, rcu);
133-
134-
error:
135116
return ret;
136117
}
137-
138118
EXPORT_SYMBOL_GPL(user_update);
139119

140120
/*

0 commit comments

Comments
 (0)