security: don't use RCU accessors for cred->session_keyring

sparse complains that a bunch of places in kernel/cred.c access
cred->session_keyring without the RCU helpers required by the __rcu
annotation.

cred->session_keyring is written in the following places:

 - prepare_kernel_cred() [in a new cred struct]
 - keyctl_session_to_parent() [in a new cred struct]
 - prepare_creds [in a new cred struct, via memcpy]
 - install_session_keyring_to_cred()
  - from install_session_keyring() on new creds
  - from join_session_keyring() on new creds [twice]
  - from umh_keys_init()
   - from call_usermodehelper_exec_async() on new creds

All of these writes are before the creds are committed; therefore,
cred->session_keyring doesn't need RCU protection.

Remove the __rcu annotation and fix up all existing users that use __rcu.

Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: James Morris <james.morris@microsoft.com>
This commit is contained in:
Jann Horn
2019-03-27 16:39:38 +01:00
committed by James Morris
parent 1b26fcdb74
commit 5c7e372caa
3 changed files with 7 additions and 16 deletions
+4 -8
View File
@@ -227,6 +227,7 @@ static int install_process_keyring(void)
* Install the given keyring as the session keyring of the given credentials
* struct, replacing the existing one if any. If the given keyring is NULL,
* then install a new anonymous session keyring.
* @cred can not be in use by any task yet.
*
* Return: 0 on success; -errno on failure.
*/
@@ -254,7 +255,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
/* install the keyring */
old = cred->session_keyring;
rcu_assign_pointer(cred->session_keyring, keyring);
cred->session_keyring = keyring;
if (old)
key_put(old);
@@ -392,11 +393,8 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
/* search the session keyring */
if (ctx->cred->session_keyring) {
rcu_read_lock();
key_ref = keyring_search_aux(
make_key_ref(rcu_dereference(ctx->cred->session_keyring), 1),
ctx);
rcu_read_unlock();
make_key_ref(ctx->cred->session_keyring, 1), ctx);
if (!IS_ERR(key_ref))
goto found;
@@ -612,10 +610,8 @@ try_again:
goto reget_creds;
}
rcu_read_lock();
key = rcu_dereference(ctx.cred->session_keyring);
key = ctx.cred->session_keyring;
__key_get(key);
rcu_read_unlock();
key_ref = make_key_ref(key, 1);
break;