keys: sparse: Fix key_fs[ug]id_changed()
authorDavid Howells <dhowells@redhat.com>
Wed, 22 May 2019 13:06:51 +0000 (14:06 +0100)
committerDavid Howells <dhowells@redhat.com>
Wed, 22 May 2019 13:06:51 +0000 (14:06 +0100)
Sparse warnings are incurred by key_fs[ug]id_changed() due to unprotected
accesses of tsk->cred, which is marked __rcu.

Fix this by passing the new cred struct to these functions from
commit_creds() rather than the task pointer.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jamorris@linux.microsoft.com>
include/linux/key.h
kernel/cred.c
security/keys/process_keys.c

index 7099985e35a99fbfd2cd783d1c5995f436dd06ed..1f09aad1c98c403dde2ba493428355de2335f997 100644 (file)
@@ -402,8 +402,8 @@ extern struct ctl_table key_sysctls[];
  * the userspace interface
  */
 extern int install_thread_keyring_to_cred(struct cred *cred);
-extern void key_fsuid_changed(struct task_struct *tsk);
-extern void key_fsgid_changed(struct task_struct *tsk);
+extern void key_fsuid_changed(struct cred *new_cred);
+extern void key_fsgid_changed(struct cred *new_cred);
 extern void key_init(void);
 
 #else /* CONFIG_KEYS */
@@ -418,8 +418,8 @@ extern void key_init(void);
 #define make_key_ref(k, p)             NULL
 #define key_ref_to_ptr(k)              NULL
 #define is_key_possessed(k)            0
-#define key_fsuid_changed(t)           do { } while(0)
-#define key_fsgid_changed(t)           do { } while(0)
+#define key_fsuid_changed(c)           do { } while(0)
+#define key_fsgid_changed(c)           do { } while(0)
 #define key_init()                     do { } while(0)
 
 #endif /* CONFIG_KEYS */
index 45d77284aed0a91383e71e53bfadf6dd5017f7e0..3bd40de9e19244f0dafb76602f2b44ee1e9fd138 100644 (file)
@@ -455,9 +455,9 @@ int commit_creds(struct cred *new)
 
        /* alter the thread keyring */
        if (!uid_eq(new->fsuid, old->fsuid))
-               key_fsuid_changed(task);
+               key_fsuid_changed(new);
        if (!gid_eq(new->fsgid, old->fsgid))
-               key_fsgid_changed(task);
+               key_fsgid_changed(new);
 
        /* do it
         * RLIMIT_NPROC limits on user->processes have already been checked
index f05f7125a7d5dcbcd4ca8f743d0cc429dcb9622b..ba5d3172cafe8b0764c0beb74e28088325b8c6cd 100644 (file)
@@ -293,28 +293,26 @@ static int install_session_keyring(struct key *keyring)
 /*
  * Handle the fsuid changing.
  */
-void key_fsuid_changed(struct task_struct *tsk)
+void key_fsuid_changed(struct cred *new_cred)
 {
        /* update the ownership of the thread keyring */
-       BUG_ON(!tsk->cred);
-       if (tsk->cred->thread_keyring) {
-               down_write(&tsk->cred->thread_keyring->sem);
-               tsk->cred->thread_keyring->uid = tsk->cred->fsuid;
-               up_write(&tsk->cred->thread_keyring->sem);
+       if (new_cred->thread_keyring) {
+               down_write(&new_cred->thread_keyring->sem);
+               new_cred->thread_keyring->uid = new_cred->fsuid;
+               up_write(&new_cred->thread_keyring->sem);
        }
 }
 
 /*
  * Handle the fsgid changing.
  */
-void key_fsgid_changed(struct task_struct *tsk)
+void key_fsgid_changed(struct cred *new_cred)
 {
        /* update the ownership of the thread keyring */
-       BUG_ON(!tsk->cred);
-       if (tsk->cred->thread_keyring) {
-               down_write(&tsk->cred->thread_keyring->sem);
-               tsk->cred->thread_keyring->gid = tsk->cred->fsgid;
-               up_write(&tsk->cred->thread_keyring->sem);
+       if (new_cred->thread_keyring) {
+               down_write(&new_cred->thread_keyring->sem);
+               new_cred->thread_keyring->gid = new_cred->fsgid;
+               up_write(&new_cred->thread_keyring->sem);
        }
 }