diff options
Diffstat (limited to 'security/keys/request_key.c')
| -rw-r--r-- | security/keys/request_key.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 03fe63ed55bd..d8c1a6a0fb08 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
| @@ -68,7 +68,8 @@ static int call_sbin_request_key(struct key_construction *cons, | |||
| 68 | { | 68 | { |
| 69 | const struct cred *cred = current_cred(); | 69 | const struct cred *cred = current_cred(); |
| 70 | key_serial_t prkey, sskey; | 70 | key_serial_t prkey, sskey; |
| 71 | struct key *key = cons->key, *authkey = cons->authkey, *keyring; | 71 | struct key *key = cons->key, *authkey = cons->authkey, *keyring, |
| 72 | *session; | ||
| 72 | char *argv[9], *envp[3], uid_str[12], gid_str[12]; | 73 | char *argv[9], *envp[3], uid_str[12], gid_str[12]; |
| 73 | char key_str[12], keyring_str[3][12]; | 74 | char key_str[12], keyring_str[3][12]; |
| 74 | char desc[20]; | 75 | char desc[20]; |
| @@ -93,7 +94,7 @@ static int call_sbin_request_key(struct key_construction *cons, | |||
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | /* attach the auth key to the session keyring */ | 96 | /* attach the auth key to the session keyring */ |
| 96 | ret = __key_link(keyring, authkey); | 97 | ret = key_link(keyring, authkey); |
| 97 | if (ret < 0) | 98 | if (ret < 0) |
| 98 | goto error_link; | 99 | goto error_link; |
| 99 | 100 | ||
| @@ -112,10 +113,12 @@ static int call_sbin_request_key(struct key_construction *cons, | |||
| 112 | if (cred->tgcred->process_keyring) | 113 | if (cred->tgcred->process_keyring) |
| 113 | prkey = cred->tgcred->process_keyring->serial; | 114 | prkey = cred->tgcred->process_keyring->serial; |
| 114 | 115 | ||
| 115 | if (cred->tgcred->session_keyring) | 116 | rcu_read_lock(); |
| 116 | sskey = rcu_dereference(cred->tgcred->session_keyring)->serial; | 117 | session = rcu_dereference(cred->tgcred->session_keyring); |
| 117 | else | 118 | if (!session) |
| 118 | sskey = cred->user->session_keyring->serial; | 119 | session = cred->user->session_keyring; |
| 120 | sskey = session->serial; | ||
| 121 | rcu_read_unlock(); | ||
| 119 | 122 | ||
| 120 | sprintf(keyring_str[2], "%d", sskey); | 123 | sprintf(keyring_str[2], "%d", sskey); |
| 121 | 124 | ||
| @@ -336,8 +339,10 @@ static int construct_alloc_key(struct key_type *type, | |||
| 336 | 339 | ||
| 337 | key_already_present: | 340 | key_already_present: |
| 338 | mutex_unlock(&key_construction_mutex); | 341 | mutex_unlock(&key_construction_mutex); |
| 339 | if (dest_keyring) | 342 | if (dest_keyring) { |
| 343 | __key_link(dest_keyring, key_ref_to_ptr(key_ref)); | ||
| 340 | up_write(&dest_keyring->sem); | 344 | up_write(&dest_keyring->sem); |
| 345 | } | ||
| 341 | mutex_unlock(&user->cons_lock); | 346 | mutex_unlock(&user->cons_lock); |
| 342 | key_put(key); | 347 | key_put(key); |
| 343 | *_key = key = key_ref_to_ptr(key_ref); | 348 | *_key = key = key_ref_to_ptr(key_ref); |
| @@ -428,6 +433,11 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 428 | 433 | ||
| 429 | if (!IS_ERR(key_ref)) { | 434 | if (!IS_ERR(key_ref)) { |
| 430 | key = key_ref_to_ptr(key_ref); | 435 | key = key_ref_to_ptr(key_ref); |
| 436 | if (dest_keyring) { | ||
| 437 | construct_get_dest_keyring(&dest_keyring); | ||
| 438 | key_link(dest_keyring, key); | ||
| 439 | key_put(dest_keyring); | ||
| 440 | } | ||
| 431 | } else if (PTR_ERR(key_ref) != -EAGAIN) { | 441 | } else if (PTR_ERR(key_ref) != -EAGAIN) { |
| 432 | key = ERR_CAST(key_ref); | 442 | key = ERR_CAST(key_ref); |
| 433 | } else { | 443 | } else { |
