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>
#ifdef CONFIG_KEYS
unsigned char jit_keyring; /* default keyring to attach requested
* keys to */
#ifdef CONFIG_KEYS
unsigned char jit_keyring; /* default keyring to attach requested
* keys to */
- struct key __rcu *session_keyring; /* keyring inherited over fork */
+ struct key *session_keyring; /* keyring inherited over fork */
struct key *process_keyring; /* keyring private to this process */
struct key *thread_keyring; /* keyring private to this thread */
struct key *request_key_auth; /* assumed request_key authority */
struct key *process_keyring; /* keyring private to this process */
struct key *thread_keyring; /* keyring private to this thread */
struct key *request_key_auth; /* assumed request_key authority */
* 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.
* 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.
*/
*
* Return: 0 on success; -errno on failure.
*/
/* install the keyring */
old = cred->session_keyring;
/* install the keyring */
old = cred->session_keyring;
- rcu_assign_pointer(cred->session_keyring, keyring);
+ cred->session_keyring = keyring;
/* search the session keyring */
if (ctx->cred->session_keyring) {
/* search the session keyring */
if (ctx->cred->session_keyring) {
key_ref = keyring_search_aux(
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;
if (!IS_ERR(key_ref))
goto found;
- rcu_read_lock();
- key = rcu_dereference(ctx.cred->session_keyring);
+ key = ctx.cred->session_keyring;
key_ref = make_key_ref(key, 1);
break;
key_ref = make_key_ref(key, 1);
break;
prkey = cred->process_keyring->serial;
sprintf(keyring_str[1], "%d", prkey);
prkey = cred->process_keyring->serial;
sprintf(keyring_str[1], "%d", prkey);
- rcu_read_lock();
- session = rcu_dereference(cred->session_keyring);
+ session = cred->session_keyring;
if (!session)
session = cred->user->session_keyring;
sskey = session->serial;
if (!session)
session = cred->user->session_keyring;
sskey = session->serial;
sprintf(keyring_str[2], "%d", sskey);
sprintf(keyring_str[2], "%d", sskey);
/* fall through */
case KEY_REQKEY_DEFL_SESSION_KEYRING:
/* fall through */
case KEY_REQKEY_DEFL_SESSION_KEYRING:
- rcu_read_lock();
- dest_keyring = key_get(
- rcu_dereference(cred->session_keyring));
- rcu_read_unlock();
+ dest_keyring = key_get(cred->session_keyring);