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 7099985..1f09aad 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 45d7728..3bd40de 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 f05f712..ba5d317 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);
        }
 }