summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-06-26 16:02:32 -0400
committerDavid Howells <dhowells@redhat.com>2019-06-26 16:02:32 -0400
commit0f44e4d976f96c6439da0d6717238efa4b91196e (patch)
tree3cec4bc4ef3faa4e61058e3aff066a7bec1c9d37
parentb206f281d0ee14969878469816a69db22d5838e8 (diff)
keys: Move the user and user-session keyrings to the user_namespace
Move the user and user-session keyrings to the user_namespace struct rather than pinning them from the user_struct struct. This prevents these keyrings from propagating across user-namespaces boundaries with regard to the KEY_SPEC_* flags, thereby making them more useful in a containerised environment. The issue is that a single user_struct may be represent UIDs in several different namespaces. The way the patch does this is by attaching a 'register keyring' in each user_namespace and then sticking the user and user-session keyrings into that. It can then be searched to retrieve them. Signed-off-by: David Howells <dhowells@redhat.com> cc: Jann Horn <jannh@google.com>
-rw-r--r--include/linux/sched/user.h14
-rw-r--r--include/linux/user_namespace.h9
-rw-r--r--kernel/user.c7
-rw-r--r--kernel/user_namespace.c4
-rw-r--r--security/keys/internal.h3
-rw-r--r--security/keys/keyring.c1
-rw-r--r--security/keys/persistent.c8
-rw-r--r--security/keys/process_keys.c259
-rw-r--r--security/keys/request_key.c20
9 files changed, 196 insertions, 129 deletions
diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h
index 468d2565a9fe..917d88edb7b9 100644
--- a/include/linux/sched/user.h
+++ b/include/linux/sched/user.h
@@ -7,8 +7,6 @@
7#include <linux/refcount.h> 7#include <linux/refcount.h>
8#include <linux/ratelimit.h> 8#include <linux/ratelimit.h>
9 9
10struct key;
11
12/* 10/*
13 * Some day this will be a full-fledged user tracking system.. 11 * Some day this will be a full-fledged user tracking system..
14 */ 12 */
@@ -30,18 +28,6 @@ struct user_struct {
30 unsigned long unix_inflight; /* How many files in flight in unix sockets */ 28 unsigned long unix_inflight; /* How many files in flight in unix sockets */
31 atomic_long_t pipe_bufs; /* how many pages are allocated in pipe buffers */ 29 atomic_long_t pipe_bufs; /* how many pages are allocated in pipe buffers */
32 30
33#ifdef CONFIG_KEYS
34 /*
35 * These pointers can only change from NULL to a non-NULL value once.
36 * Writes are protected by key_user_keyring_mutex.
37 * Unlocked readers should use READ_ONCE() unless they know that
38 * install_user_keyrings() has been called successfully (which sets
39 * these members to non-NULL values, preventing further modifications).
40 */
41 struct key *uid_keyring; /* UID specific keyring */
42 struct key *session_keyring; /* UID's default session keyring */
43#endif
44
45 /* Hash table maintenance information */ 31 /* Hash table maintenance information */
46 struct hlist_node uidhash_node; 32 struct hlist_node uidhash_node;
47 kuid_t uid; 33 kuid_t uid;
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 90457015fa3f..fb9f4f799554 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -65,14 +65,19 @@ struct user_namespace {
65 unsigned long flags; 65 unsigned long flags;
66 66
67#ifdef CONFIG_KEYS 67#ifdef CONFIG_KEYS
68 /* List of joinable keyrings in this namespace */ 68 /* List of joinable keyrings in this namespace. Modification access of
69 * these pointers is controlled by keyring_sem. Once
70 * user_keyring_register is set, it won't be changed, so it can be
71 * accessed directly with READ_ONCE().
72 */
69 struct list_head keyring_name_list; 73 struct list_head keyring_name_list;
74 struct key *user_keyring_register;
75 struct rw_semaphore keyring_sem;
70#endif 76#endif
71 77
72 /* Register of per-UID persistent keyrings for this namespace */ 78 /* Register of per-UID persistent keyrings for this namespace */
73#ifdef CONFIG_PERSISTENT_KEYRINGS 79#ifdef CONFIG_PERSISTENT_KEYRINGS
74 struct key *persistent_keyring_register; 80 struct key *persistent_keyring_register;
75 struct rw_semaphore persistent_keyring_register_sem;
76#endif 81#endif
77 struct work_struct work; 82 struct work_struct work;
78#ifdef CONFIG_SYSCTL 83#ifdef CONFIG_SYSCTL
diff --git a/kernel/user.c b/kernel/user.c
index 50979fd1b7aa..f8519b62cf9a 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -64,10 +64,7 @@ struct user_namespace init_user_ns = {
64 .flags = USERNS_INIT_FLAGS, 64 .flags = USERNS_INIT_FLAGS,
65#ifdef CONFIG_KEYS 65#ifdef CONFIG_KEYS
66 .keyring_name_list = LIST_HEAD_INIT(init_user_ns.keyring_name_list), 66 .keyring_name_list = LIST_HEAD_INIT(init_user_ns.keyring_name_list),
67#endif 67 .keyring_sem = __RWSEM_INITIALIZER(init_user_ns.keyring_sem),
68#ifdef CONFIG_PERSISTENT_KEYRINGS
69 .persistent_keyring_register_sem =
70 __RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem),
71#endif 68#endif
72}; 69};
73EXPORT_SYMBOL_GPL(init_user_ns); 70EXPORT_SYMBOL_GPL(init_user_ns);
@@ -143,8 +140,6 @@ static void free_user(struct user_struct *up, unsigned long flags)
143{ 140{
144 uid_hash_remove(up); 141 uid_hash_remove(up);
145 spin_unlock_irqrestore(&uidhash_lock, flags); 142 spin_unlock_irqrestore(&uidhash_lock, flags);
146 key_put(up->uid_keyring);
147 key_put(up->session_keyring);
148 kmem_cache_free(uid_cachep, up); 143 kmem_cache_free(uid_cachep, up);
149} 144}
150 145
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index bda6e890ad88..c87c2ecc7085 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -135,9 +135,7 @@ int create_user_ns(struct cred *new)
135 135
136#ifdef CONFIG_KEYS 136#ifdef CONFIG_KEYS
137 INIT_LIST_HEAD(&ns->keyring_name_list); 137 INIT_LIST_HEAD(&ns->keyring_name_list);
138#endif 138 init_rwsem(&ns->keyring_sem);
139#ifdef CONFIG_PERSISTENT_KEYRINGS
140 init_rwsem(&ns->persistent_keyring_register_sem);
141#endif 139#endif
142 ret = -ENOMEM; 140 ret = -ENOMEM;
143 if (!setup_userns_sysctls(ns)) 141 if (!setup_userns_sysctls(ns))
diff --git a/security/keys/internal.h b/security/keys/internal.h
index aa361299a3ec..d3a9439e2386 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -148,7 +148,8 @@ extern key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx)
148 148
149extern struct key *find_keyring_by_name(const char *name, bool uid_keyring); 149extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
150 150
151extern int install_user_keyrings(void); 151extern int look_up_user_keyrings(struct key **, struct key **);
152extern struct key *get_user_session_keyring_rcu(const struct cred *);
152extern int install_thread_keyring_to_cred(struct cred *); 153extern int install_thread_keyring_to_cred(struct cred *);
153extern int install_process_keyring_to_cred(struct cred *); 154extern int install_process_keyring_to_cred(struct cred *);
154extern int install_session_keyring_to_cred(struct cred *, struct key *); 155extern int install_session_keyring_to_cred(struct cred *, struct key *);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index fe851292509e..3663e5168583 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -62,6 +62,7 @@ void key_free_user_ns(struct user_namespace *ns)
62 list_del_init(&ns->keyring_name_list); 62 list_del_init(&ns->keyring_name_list);
63 write_unlock(&keyring_name_lock); 63 write_unlock(&keyring_name_lock);
64 64
65 key_put(ns->user_keyring_register);
65#ifdef CONFIG_PERSISTENT_KEYRINGS 66#ifdef CONFIG_PERSISTENT_KEYRINGS
66 key_put(ns->persistent_keyring_register); 67 key_put(ns->persistent_keyring_register);
67#endif 68#endif
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index fc29ec59efa7..90303fe4a394 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -91,9 +91,9 @@ static long key_get_persistent(struct user_namespace *ns, kuid_t uid,
91 91
92 if (ns->persistent_keyring_register) { 92 if (ns->persistent_keyring_register) {
93 reg_ref = make_key_ref(ns->persistent_keyring_register, true); 93 reg_ref = make_key_ref(ns->persistent_keyring_register, true);
94 down_read(&ns->persistent_keyring_register_sem); 94 down_read(&ns->keyring_sem);
95 persistent_ref = find_key_to_update(reg_ref, &index_key); 95 persistent_ref = find_key_to_update(reg_ref, &index_key);
96 up_read(&ns->persistent_keyring_register_sem); 96 up_read(&ns->keyring_sem);
97 97
98 if (persistent_ref) 98 if (persistent_ref)
99 goto found; 99 goto found;
@@ -102,9 +102,9 @@ static long key_get_persistent(struct user_namespace *ns, kuid_t uid,
102 /* It wasn't in the register, so we'll need to create it. We might 102 /* It wasn't in the register, so we'll need to create it. We might
103 * also need to create the register. 103 * also need to create the register.
104 */ 104 */
105 down_write(&ns->persistent_keyring_register_sem); 105 down_write(&ns->keyring_sem);
106 persistent_ref = key_create_persistent(ns, uid, &index_key); 106 persistent_ref = key_create_persistent(ns, uid, &index_key);
107 up_write(&ns->persistent_keyring_register_sem); 107 up_write(&ns->keyring_sem);
108 if (!IS_ERR(persistent_ref)) 108 if (!IS_ERR(persistent_ref))
109 goto found; 109 goto found;
110 110
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index b07f768d23dc..f74d64215942 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -19,15 +19,13 @@
19#include <linux/security.h> 19#include <linux/security.h>
20#include <linux/user_namespace.h> 20#include <linux/user_namespace.h>
21#include <linux/uaccess.h> 21#include <linux/uaccess.h>
22#include <linux/init_task.h>
22#include <keys/request_key_auth-type.h> 23#include <keys/request_key_auth-type.h>
23#include "internal.h" 24#include "internal.h"
24 25
25/* Session keyring create vs join semaphore */ 26/* Session keyring create vs join semaphore */
26static DEFINE_MUTEX(key_session_mutex); 27static DEFINE_MUTEX(key_session_mutex);
27 28
28/* User keyring creation semaphore */
29static DEFINE_MUTEX(key_user_keyring_mutex);
30
31/* The root user's tracking struct */ 29/* The root user's tracking struct */
32struct key_user root_key_user = { 30struct key_user root_key_user = {
33 .usage = REFCOUNT_INIT(3), 31 .usage = REFCOUNT_INIT(3),
@@ -39,99 +37,186 @@ struct key_user root_key_user = {
39}; 37};
40 38
41/* 39/*
42 * Install the user and user session keyrings for the current process's UID. 40 * Get or create a user register keyring.
41 */
42static struct key *get_user_register(struct user_namespace *user_ns)
43{
44 struct key *reg_keyring = READ_ONCE(user_ns->user_keyring_register);
45
46 if (reg_keyring)
47 return reg_keyring;
48
49 down_write(&user_ns->keyring_sem);
50
51 /* Make sure there's a register keyring. It gets owned by the
52 * user_namespace's owner.
53 */
54 reg_keyring = user_ns->user_keyring_register;
55 if (!reg_keyring) {
56 reg_keyring = keyring_alloc(".user_reg",
57 user_ns->owner, INVALID_GID,
58 &init_cred,
59 KEY_POS_WRITE | KEY_POS_SEARCH |
60 KEY_USR_VIEW | KEY_USR_READ,
61 0,
62 NULL, NULL);
63 if (!IS_ERR(reg_keyring))
64 smp_store_release(&user_ns->user_keyring_register,
65 reg_keyring);
66 }
67
68 up_write(&user_ns->keyring_sem);
69
70 /* We don't return a ref since the keyring is pinned by the user_ns */
71 return reg_keyring;
72}
73
74/*
75 * Look up the user and user session keyrings for the current process's UID,
76 * creating them if they don't exist.
43 */ 77 */
44int install_user_keyrings(void) 78int look_up_user_keyrings(struct key **_user_keyring,
79 struct key **_user_session_keyring)
45{ 80{
46 struct user_struct *user; 81 const struct cred *cred = current_cred();
47 const struct cred *cred; 82 struct user_namespace *user_ns = current_user_ns();
48 struct key *uid_keyring, *session_keyring; 83 struct key *reg_keyring, *uid_keyring, *session_keyring;
49 key_perm_t user_keyring_perm; 84 key_perm_t user_keyring_perm;
85 key_ref_t uid_keyring_r, session_keyring_r;
86 uid_t uid = from_kuid(user_ns, cred->user->uid);
50 char buf[20]; 87 char buf[20];
51 int ret; 88 int ret;
52 uid_t uid;
53 89
54 user_keyring_perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL; 90 user_keyring_perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL;
55 cred = current_cred();
56 user = cred->user;
57 uid = from_kuid(cred->user_ns, user->uid);
58 91
59 kenter("%p{%u}", user, uid); 92 kenter("%u", uid);
60 93
61 if (READ_ONCE(user->uid_keyring) && READ_ONCE(user->session_keyring)) { 94 reg_keyring = get_user_register(user_ns);
62 kleave(" = 0 [exist]"); 95 if (IS_ERR(reg_keyring))
63 return 0; 96 return PTR_ERR(reg_keyring);
64 }
65 97
66 mutex_lock(&key_user_keyring_mutex); 98 down_write(&user_ns->keyring_sem);
67 ret = 0; 99 ret = 0;
68 100
69 if (!user->uid_keyring) { 101 /* Get the user keyring. Note that there may be one in existence
70 /* get the UID-specific keyring 102 * already as it may have been pinned by a session, but the user_struct
71 * - there may be one in existence already as it may have been 103 * pointing to it may have been destroyed by setuid.
72 * pinned by a session, but the user_struct pointing to it 104 */
73 * may have been destroyed by setuid */ 105 snprintf(buf, sizeof(buf), "_uid.%u", uid);
74 sprintf(buf, "_uid.%u", uid); 106 uid_keyring_r = keyring_search(make_key_ref(reg_keyring, true),
75 107 &key_type_keyring, buf, false);
76 uid_keyring = find_keyring_by_name(buf, true); 108 kdebug("_uid %p", uid_keyring_r);
109 if (uid_keyring_r == ERR_PTR(-EAGAIN)) {
110 uid_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
111 cred, user_keyring_perm,
112 KEY_ALLOC_UID_KEYRING |
113 KEY_ALLOC_IN_QUOTA,
114 NULL, reg_keyring);
77 if (IS_ERR(uid_keyring)) { 115 if (IS_ERR(uid_keyring)) {
78 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, 116 ret = PTR_ERR(uid_keyring);
79 cred, user_keyring_perm, 117 goto error;
80 KEY_ALLOC_UID_KEYRING |
81 KEY_ALLOC_IN_QUOTA,
82 NULL, NULL);
83 if (IS_ERR(uid_keyring)) {
84 ret = PTR_ERR(uid_keyring);
85 goto error;
86 }
87 } 118 }
119 } else if (IS_ERR(uid_keyring_r)) {
120 ret = PTR_ERR(uid_keyring_r);
121 goto error;
122 } else {
123 uid_keyring = key_ref_to_ptr(uid_keyring_r);
124 }
88 125
89 /* get a default session keyring (which might also exist 126 /* Get a default session keyring (which might also exist already) */
90 * already) */ 127 snprintf(buf, sizeof(buf), "_uid_ses.%u", uid);
91 sprintf(buf, "_uid_ses.%u", uid); 128 session_keyring_r = keyring_search(make_key_ref(reg_keyring, true),
92 129 &key_type_keyring, buf, false);
93 session_keyring = find_keyring_by_name(buf, true); 130 kdebug("_uid_ses %p", session_keyring_r);
131 if (session_keyring_r == ERR_PTR(-EAGAIN)) {
132 session_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
133 cred, user_keyring_perm,
134 KEY_ALLOC_UID_KEYRING |
135 KEY_ALLOC_IN_QUOTA,
136 NULL, NULL);
94 if (IS_ERR(session_keyring)) { 137 if (IS_ERR(session_keyring)) {
95 session_keyring = 138 ret = PTR_ERR(session_keyring);
96 keyring_alloc(buf, user->uid, INVALID_GID, 139 goto error_release;
97 cred, user_keyring_perm,
98 KEY_ALLOC_UID_KEYRING |
99 KEY_ALLOC_IN_QUOTA,
100 NULL, NULL);
101 if (IS_ERR(session_keyring)) {
102 ret = PTR_ERR(session_keyring);
103 goto error_release;
104 }
105
106 /* we install a link from the user session keyring to
107 * the user keyring */
108 ret = key_link(session_keyring, uid_keyring);
109 if (ret < 0)
110 goto error_release_both;
111 } 140 }
112 141
113 /* install the keyrings */ 142 /* We install a link from the user session keyring to
114 /* paired with READ_ONCE() */ 143 * the user keyring.
115 smp_store_release(&user->uid_keyring, uid_keyring); 144 */
116 /* paired with READ_ONCE() */ 145 ret = key_link(session_keyring, uid_keyring);
117 smp_store_release(&user->session_keyring, session_keyring); 146 if (ret < 0)
147 goto error_release_session;
148
149 /* And only then link the user-session keyring to the
150 * register.
151 */
152 ret = key_link(reg_keyring, session_keyring);
153 if (ret < 0)
154 goto error_release_session;
155 } else if (IS_ERR(session_keyring_r)) {
156 ret = PTR_ERR(session_keyring_r);
157 goto error_release;
158 } else {
159 session_keyring = key_ref_to_ptr(session_keyring_r);
118 } 160 }
119 161
120 mutex_unlock(&key_user_keyring_mutex); 162 up_write(&user_ns->keyring_sem);
163
164 if (_user_session_keyring)
165 *_user_session_keyring = session_keyring;
166 else
167 key_put(session_keyring);
168 if (_user_keyring)
169 *_user_keyring = uid_keyring;
170 else
171 key_put(uid_keyring);
121 kleave(" = 0"); 172 kleave(" = 0");
122 return 0; 173 return 0;
123 174
124error_release_both: 175error_release_session:
125 key_put(session_keyring); 176 key_put(session_keyring);
126error_release: 177error_release:
127 key_put(uid_keyring); 178 key_put(uid_keyring);
128error: 179error:
129 mutex_unlock(&key_user_keyring_mutex); 180 up_write(&user_ns->keyring_sem);
130 kleave(" = %d", ret); 181 kleave(" = %d", ret);
131 return ret; 182 return ret;
132} 183}
133 184
134/* 185/*
186 * Get the user session keyring if it exists, but don't create it if it
187 * doesn't.
188 */
189struct key *get_user_session_keyring_rcu(const struct cred *cred)
190{
191 struct key *reg_keyring = READ_ONCE(cred->user_ns->user_keyring_register);
192 key_ref_t session_keyring_r;
193 char buf[20];
194
195 struct keyring_search_context ctx = {
196 .index_key.type = &key_type_keyring,
197 .index_key.description = buf,
198 .cred = cred,
199 .match_data.cmp = key_default_cmp,
200 .match_data.raw_data = buf,
201 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
202 .flags = KEYRING_SEARCH_DO_STATE_CHECK,
203 };
204
205 if (!reg_keyring)
206 return NULL;
207
208 ctx.index_key.desc_len = snprintf(buf, sizeof(buf), "_uid_ses.%u",
209 from_kuid(cred->user_ns,
210 cred->user->uid));
211
212 session_keyring_r = keyring_search_rcu(make_key_ref(reg_keyring, true),
213 &ctx);
214 if (IS_ERR(session_keyring_r))
215 return NULL;
216 return key_ref_to_ptr(session_keyring_r);
217}
218
219/*
135 * Install a thread keyring to the given credentials struct if it didn't have 220 * Install a thread keyring to the given credentials struct if it didn't have
136 * one already. This is allowed to overrun the quota. 221 * one already. This is allowed to overrun the quota.
137 * 222 *
@@ -340,6 +425,7 @@ void key_fsgid_changed(struct cred *new_cred)
340 */ 425 */
341key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx) 426key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx)
342{ 427{
428 struct key *user_session;
343 key_ref_t key_ref, ret, err; 429 key_ref_t key_ref, ret, err;
344 const struct cred *cred = ctx->cred; 430 const struct cred *cred = ctx->cred;
345 431
@@ -415,10 +501,11 @@ key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx)
415 } 501 }
416 } 502 }
417 /* or search the user-session keyring */ 503 /* or search the user-session keyring */
418 else if (READ_ONCE(cred->user->session_keyring)) { 504 else if ((user_session = get_user_session_keyring_rcu(cred))) {
419 key_ref = keyring_search_rcu( 505 key_ref = keyring_search_rcu(make_key_ref(user_session, 1),
420 make_key_ref(READ_ONCE(cred->user->session_keyring), 1), 506 ctx);
421 ctx); 507 key_put(user_session);
508
422 if (!IS_ERR(key_ref)) 509 if (!IS_ERR(key_ref))
423 goto found; 510 goto found;
424 511
@@ -535,7 +622,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
535 KEYRING_SEARCH_RECURSE), 622 KEYRING_SEARCH_RECURSE),
536 }; 623 };
537 struct request_key_auth *rka; 624 struct request_key_auth *rka;
538 struct key *key; 625 struct key *key, *user_session;
539 key_ref_t key_ref, skey_ref; 626 key_ref_t key_ref, skey_ref;
540 int ret; 627 int ret;
541 628
@@ -584,20 +671,20 @@ try_again:
584 if (!ctx.cred->session_keyring) { 671 if (!ctx.cred->session_keyring) {
585 /* always install a session keyring upon access if one 672 /* always install a session keyring upon access if one
586 * doesn't exist yet */ 673 * doesn't exist yet */
587 ret = install_user_keyrings(); 674 ret = look_up_user_keyrings(NULL, &user_session);
588 if (ret < 0) 675 if (ret < 0)
589 goto error; 676 goto error;
590 if (lflags & KEY_LOOKUP_CREATE) 677 if (lflags & KEY_LOOKUP_CREATE)
591 ret = join_session_keyring(NULL); 678 ret = join_session_keyring(NULL);
592 else 679 else
593 ret = install_session_keyring( 680 ret = install_session_keyring(user_session);
594 ctx.cred->user->session_keyring);
595 681
682 key_put(user_session);
596 if (ret < 0) 683 if (ret < 0)
597 goto error; 684 goto error;
598 goto reget_creds; 685 goto reget_creds;
599 } else if (ctx.cred->session_keyring == 686 } else if (test_bit(KEY_FLAG_UID_KEYRING,
600 READ_ONCE(ctx.cred->user->session_keyring) && 687 &ctx.cred->session_keyring->flags) &&
601 lflags & KEY_LOOKUP_CREATE) { 688 lflags & KEY_LOOKUP_CREATE) {
602 ret = join_session_keyring(NULL); 689 ret = join_session_keyring(NULL);
603 if (ret < 0) 690 if (ret < 0)
@@ -611,26 +698,16 @@ try_again:
611 break; 698 break;
612 699
613 case KEY_SPEC_USER_KEYRING: 700 case KEY_SPEC_USER_KEYRING:
614 if (!READ_ONCE(ctx.cred->user->uid_keyring)) { 701 ret = look_up_user_keyrings(&key, NULL);
615 ret = install_user_keyrings(); 702 if (ret < 0)
616 if (ret < 0) 703 goto error;
617 goto error;
618 }
619
620 key = ctx.cred->user->uid_keyring;
621 __key_get(key);
622 key_ref = make_key_ref(key, 1); 704 key_ref = make_key_ref(key, 1);
623 break; 705 break;
624 706
625 case KEY_SPEC_USER_SESSION_KEYRING: 707 case KEY_SPEC_USER_SESSION_KEYRING:
626 if (!READ_ONCE(ctx.cred->user->session_keyring)) { 708 ret = look_up_user_keyrings(NULL, &key);
627 ret = install_user_keyrings(); 709 if (ret < 0)
628 if (ret < 0) 710 goto error;
629 goto error;
630 }
631
632 key = ctx.cred->user->session_keyring;
633 __key_get(key);
634 key_ref = make_key_ref(key, 1); 711 key_ref = make_key_ref(key, 1);
635 break; 712 break;
636 713
@@ -879,7 +956,7 @@ void key_change_session_keyring(struct callback_head *twork)
879 */ 956 */
880static int __init init_root_keyring(void) 957static int __init init_root_keyring(void)
881{ 958{
882 return install_user_keyrings(); 959 return look_up_user_keyrings(NULL, NULL);
883} 960}
884 961
885late_initcall(init_root_keyring); 962late_initcall(init_root_keyring);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 1ffd3803ce29..9201ca96c4df 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -121,7 +121,7 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
121 struct request_key_auth *rka = get_request_key_auth(authkey); 121 struct request_key_auth *rka = get_request_key_auth(authkey);
122 const struct cred *cred = current_cred(); 122 const struct cred *cred = current_cred();
123 key_serial_t prkey, sskey; 123 key_serial_t prkey, sskey;
124 struct key *key = rka->target_key, *keyring, *session; 124 struct key *key = rka->target_key, *keyring, *session, *user_session;
125 char *argv[9], *envp[3], uid_str[12], gid_str[12]; 125 char *argv[9], *envp[3], uid_str[12], gid_str[12];
126 char key_str[12], keyring_str[3][12]; 126 char key_str[12], keyring_str[3][12];
127 char desc[20]; 127 char desc[20];
@@ -129,9 +129,9 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
129 129
130 kenter("{%d},{%d},%s", key->serial, authkey->serial, rka->op); 130 kenter("{%d},{%d},%s", key->serial, authkey->serial, rka->op);
131 131
132 ret = install_user_keyrings(); 132 ret = look_up_user_keyrings(NULL, &user_session);
133 if (ret < 0) 133 if (ret < 0)
134 goto error_alloc; 134 goto error_us;
135 135
136 /* allocate a new session keyring */ 136 /* allocate a new session keyring */
137 sprintf(desc, "_req.%u", key->serial); 137 sprintf(desc, "_req.%u", key->serial);
@@ -169,7 +169,7 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
169 169
170 session = cred->session_keyring; 170 session = cred->session_keyring;
171 if (!session) 171 if (!session)
172 session = cred->user->session_keyring; 172 session = user_session;
173 sskey = session->serial; 173 sskey = session->serial;
174 174
175 sprintf(keyring_str[2], "%d", sskey); 175 sprintf(keyring_str[2], "%d", sskey);
@@ -211,6 +211,8 @@ error_link:
211 key_put(keyring); 211 key_put(keyring);
212 212
213error_alloc: 213error_alloc:
214 key_put(user_session);
215error_us:
214 complete_request_key(authkey, ret); 216 complete_request_key(authkey, ret);
215 kleave(" = %d", ret); 217 kleave(" = %d", ret);
216 return ret; 218 return ret;
@@ -317,13 +319,15 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
317 319
318 /* fall through */ 320 /* fall through */
319 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: 321 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
320 dest_keyring = 322 ret = look_up_user_keyrings(NULL, &dest_keyring);
321 key_get(READ_ONCE(cred->user->session_keyring)); 323 if (ret < 0)
324 return ret;
322 break; 325 break;
323 326
324 case KEY_REQKEY_DEFL_USER_KEYRING: 327 case KEY_REQKEY_DEFL_USER_KEYRING:
325 dest_keyring = 328 ret = look_up_user_keyrings(&dest_keyring, NULL);
326 key_get(READ_ONCE(cred->user->uid_keyring)); 329 if (ret < 0)
330 return ret;
327 break; 331 break;
328 332
329 case KEY_REQKEY_DEFL_GROUP_KEYRING: 333 case KEY_REQKEY_DEFL_GROUP_KEYRING: