aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/request_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r--security/keys/request_key.c75
1 files changed, 51 insertions, 24 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 91953c814497..8e9d93b4a402 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -76,6 +76,10 @@ static int call_sbin_request_key(struct key_construction *cons,
76 76
77 kenter("{%d},{%d},%s", key->serial, authkey->serial, op); 77 kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
78 78
79 ret = install_user_keyrings();
80 if (ret < 0)
81 goto error_alloc;
82
79 /* allocate a new session keyring */ 83 /* allocate a new session keyring */
80 sprintf(desc, "_req.%u", key->serial); 84 sprintf(desc, "_req.%u", key->serial);
81 85
@@ -165,7 +169,8 @@ error_alloc:
165 * - we ignore program failure and go on key status instead 169 * - we ignore program failure and go on key status instead
166 */ 170 */
167static int construct_key(struct key *key, const void *callout_info, 171static int construct_key(struct key *key, const void *callout_info,
168 size_t callout_len, void *aux) 172 size_t callout_len, void *aux,
173 struct key *dest_keyring)
169{ 174{
170 struct key_construction *cons; 175 struct key_construction *cons;
171 request_key_actor_t actor; 176 request_key_actor_t actor;
@@ -179,7 +184,8 @@ static int construct_key(struct key *key, const void *callout_info,
179 return -ENOMEM; 184 return -ENOMEM;
180 185
181 /* allocate an authorisation key */ 186 /* allocate an authorisation key */
182 authkey = request_key_auth_new(key, callout_info, callout_len); 187 authkey = request_key_auth_new(key, callout_info, callout_len,
188 dest_keyring);
183 if (IS_ERR(authkey)) { 189 if (IS_ERR(authkey)) {
184 kfree(cons); 190 kfree(cons);
185 ret = PTR_ERR(authkey); 191 ret = PTR_ERR(authkey);
@@ -207,27 +213,48 @@ static int construct_key(struct key *key, const void *callout_info,
207} 213}
208 214
209/* 215/*
210 * link a key to the appropriate destination keyring 216 * get the appropriate destination keyring for the request
211 * - the caller must hold a write lock on the destination keyring 217 * - we return whatever keyring we select with an extra reference upon it which
218 * the caller must release
212 */ 219 */
213static void construct_key_make_link(struct key *key, struct key *dest_keyring) 220static void construct_get_dest_keyring(struct key **_dest_keyring)
214{ 221{
222 struct request_key_auth *rka;
215 struct task_struct *tsk = current; 223 struct task_struct *tsk = current;
216 struct key *drop = NULL; 224 struct key *dest_keyring = *_dest_keyring, *authkey;
217 225
218 kenter("{%d},%p", key->serial, dest_keyring); 226 kenter("%p", dest_keyring);
219 227
220 /* find the appropriate keyring */ 228 /* find the appropriate keyring */
221 if (!dest_keyring) { 229 if (dest_keyring) {
230 /* the caller supplied one */
231 key_get(dest_keyring);
232 } else {
233 /* use a default keyring; falling through the cases until we
234 * find one that we actually have */
222 switch (tsk->jit_keyring) { 235 switch (tsk->jit_keyring) {
223 case KEY_REQKEY_DEFL_DEFAULT: 236 case KEY_REQKEY_DEFL_DEFAULT:
237 case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
238 if (tsk->request_key_auth) {
239 authkey = tsk->request_key_auth;
240 down_read(&authkey->sem);
241 rka = authkey->payload.data;
242 if (!test_bit(KEY_FLAG_REVOKED,
243 &authkey->flags))
244 dest_keyring =
245 key_get(rka->dest_keyring);
246 up_read(&authkey->sem);
247 if (dest_keyring)
248 break;
249 }
250
224 case KEY_REQKEY_DEFL_THREAD_KEYRING: 251 case KEY_REQKEY_DEFL_THREAD_KEYRING:
225 dest_keyring = tsk->thread_keyring; 252 dest_keyring = key_get(tsk->thread_keyring);
226 if (dest_keyring) 253 if (dest_keyring)
227 break; 254 break;
228 255
229 case KEY_REQKEY_DEFL_PROCESS_KEYRING: 256 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
230 dest_keyring = tsk->signal->process_keyring; 257 dest_keyring = key_get(tsk->signal->process_keyring);
231 if (dest_keyring) 258 if (dest_keyring)
232 break; 259 break;
233 260
@@ -236,17 +263,16 @@ static void construct_key_make_link(struct key *key, struct key *dest_keyring)
236 dest_keyring = key_get( 263 dest_keyring = key_get(
237 rcu_dereference(tsk->signal->session_keyring)); 264 rcu_dereference(tsk->signal->session_keyring));
238 rcu_read_unlock(); 265 rcu_read_unlock();
239 drop = dest_keyring;
240 266
241 if (dest_keyring) 267 if (dest_keyring)
242 break; 268 break;
243 269
244 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: 270 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
245 dest_keyring = tsk->user->session_keyring; 271 dest_keyring = key_get(tsk->user->session_keyring);
246 break; 272 break;
247 273
248 case KEY_REQKEY_DEFL_USER_KEYRING: 274 case KEY_REQKEY_DEFL_USER_KEYRING:
249 dest_keyring = tsk->user->uid_keyring; 275 dest_keyring = key_get(tsk->user->uid_keyring);
250 break; 276 break;
251 277
252 case KEY_REQKEY_DEFL_GROUP_KEYRING: 278 case KEY_REQKEY_DEFL_GROUP_KEYRING:
@@ -255,10 +281,9 @@ static void construct_key_make_link(struct key *key, struct key *dest_keyring)
255 } 281 }
256 } 282 }
257 283
258 /* and attach the key to it */ 284 *_dest_keyring = dest_keyring;
259 __key_link(dest_keyring, key); 285 kleave(" [dk %d]", key_serial(dest_keyring));
260 key_put(drop); 286 return;
261 kleave("");
262} 287}
263 288
264/* 289/*
@@ -288,8 +313,7 @@ static int construct_alloc_key(struct key_type *type,
288 313
289 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 314 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
290 315
291 if (dest_keyring) 316 down_write(&dest_keyring->sem);
292 down_write(&dest_keyring->sem);
293 317
294 /* attach the key to the destination keyring under lock, but we do need 318 /* attach the key to the destination keyring under lock, but we do need
295 * to do another check just in case someone beat us to it whilst we 319 * to do another check just in case someone beat us to it whilst we
@@ -301,12 +325,10 @@ static int construct_alloc_key(struct key_type *type,
301 if (!IS_ERR(key_ref)) 325 if (!IS_ERR(key_ref))
302 goto key_already_present; 326 goto key_already_present;
303 327
304 if (dest_keyring) 328 __key_link(dest_keyring, key);
305 construct_key_make_link(key, dest_keyring);
306 329
307 mutex_unlock(&key_construction_mutex); 330 mutex_unlock(&key_construction_mutex);
308 if (dest_keyring) 331 up_write(&dest_keyring->sem);
309 up_write(&dest_keyring->sem);
310 mutex_unlock(&user->cons_lock); 332 mutex_unlock(&user->cons_lock);
311 *_key = key; 333 *_key = key;
312 kleave(" = 0 [%d]", key_serial(key)); 334 kleave(" = 0 [%d]", key_serial(key));
@@ -348,21 +370,26 @@ static struct key *construct_key_and_link(struct key_type *type,
348 if (!user) 370 if (!user)
349 return ERR_PTR(-ENOMEM); 371 return ERR_PTR(-ENOMEM);
350 372
373 construct_get_dest_keyring(&dest_keyring);
374
351 ret = construct_alloc_key(type, description, dest_keyring, flags, user, 375 ret = construct_alloc_key(type, description, dest_keyring, flags, user,
352 &key); 376 &key);
353 key_user_put(user); 377 key_user_put(user);
354 378
355 if (ret == 0) { 379 if (ret == 0) {
356 ret = construct_key(key, callout_info, callout_len, aux); 380 ret = construct_key(key, callout_info, callout_len, aux,
381 dest_keyring);
357 if (ret < 0) 382 if (ret < 0)
358 goto construction_failed; 383 goto construction_failed;
359 } 384 }
360 385
386 key_put(dest_keyring);
361 return key; 387 return key;
362 388
363construction_failed: 389construction_failed:
364 key_negate_and_link(key, key_negative_timeout, NULL, NULL); 390 key_negate_and_link(key, key_negative_timeout, NULL, NULL);
365 key_put(key); 391 key_put(key);
392 key_put(dest_keyring);
366 return ERR_PTR(ret); 393 return ERR_PTR(ret);
367} 394}
368 395