1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* Manage a process's keyrings |
3 | * |
4 | * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved. |
5 | * Written by David Howells (dhowells@redhat.com) |
6 | */ |
7 | |
8 | #include <linux/init.h> |
9 | #include <linux/sched.h> |
10 | #include <linux/sched/user.h> |
11 | #include <linux/keyctl.h> |
12 | #include <linux/fs.h> |
13 | #include <linux/err.h> |
14 | #include <linux/mutex.h> |
15 | #include <linux/security.h> |
16 | #include <linux/user_namespace.h> |
17 | #include <linux/uaccess.h> |
18 | #include <linux/init_task.h> |
19 | #include <keys/request_key_auth-type.h> |
20 | #include "internal.h" |
21 | |
22 | /* Session keyring create vs join semaphore */ |
23 | static DEFINE_MUTEX(key_session_mutex); |
24 | |
25 | /* The root user's tracking struct */ |
26 | struct key_user root_key_user = { |
27 | .usage = REFCOUNT_INIT(3), |
28 | .cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock), |
29 | .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), |
30 | .nkeys = ATOMIC_INIT(2), |
31 | .nikeys = ATOMIC_INIT(2), |
32 | .uid = GLOBAL_ROOT_UID, |
33 | }; |
34 | |
35 | /* |
36 | * Get or create a user register keyring. |
37 | */ |
38 | static struct key *get_user_register(struct user_namespace *user_ns) |
39 | { |
40 | struct key *reg_keyring = READ_ONCE(user_ns->user_keyring_register); |
41 | |
42 | if (reg_keyring) |
43 | return reg_keyring; |
44 | |
45 | down_write(sem: &user_ns->keyring_sem); |
46 | |
47 | /* Make sure there's a register keyring. It gets owned by the |
48 | * user_namespace's owner. |
49 | */ |
50 | reg_keyring = user_ns->user_keyring_register; |
51 | if (!reg_keyring) { |
52 | reg_keyring = keyring_alloc(description: ".user_reg" , |
53 | uid: user_ns->owner, INVALID_GID, |
54 | cred: &init_cred, |
55 | KEY_POS_WRITE | KEY_POS_SEARCH | |
56 | KEY_USR_VIEW | KEY_USR_READ, |
57 | flags: 0, |
58 | NULL, NULL); |
59 | if (!IS_ERR(ptr: reg_keyring)) |
60 | smp_store_release(&user_ns->user_keyring_register, |
61 | reg_keyring); |
62 | } |
63 | |
64 | up_write(sem: &user_ns->keyring_sem); |
65 | |
66 | /* We don't return a ref since the keyring is pinned by the user_ns */ |
67 | return reg_keyring; |
68 | } |
69 | |
70 | /* |
71 | * Look up the user and user session keyrings for the current process's UID, |
72 | * creating them if they don't exist. |
73 | */ |
74 | int look_up_user_keyrings(struct key **_user_keyring, |
75 | struct key **_user_session_keyring) |
76 | { |
77 | const struct cred *cred = current_cred(); |
78 | struct user_namespace *user_ns = current_user_ns(); |
79 | struct key *reg_keyring, *uid_keyring, *session_keyring; |
80 | key_perm_t user_keyring_perm; |
81 | key_ref_t uid_keyring_r, session_keyring_r; |
82 | uid_t uid = from_kuid(to: user_ns, uid: cred->user->uid); |
83 | char buf[20]; |
84 | int ret; |
85 | |
86 | user_keyring_perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL; |
87 | |
88 | kenter("%u" , uid); |
89 | |
90 | reg_keyring = get_user_register(user_ns); |
91 | if (IS_ERR(ptr: reg_keyring)) |
92 | return PTR_ERR(ptr: reg_keyring); |
93 | |
94 | down_write(sem: &user_ns->keyring_sem); |
95 | ret = 0; |
96 | |
97 | /* Get the user keyring. Note that there may be one in existence |
98 | * already as it may have been pinned by a session, but the user_struct |
99 | * pointing to it may have been destroyed by setuid. |
100 | */ |
101 | snprintf(buf, size: sizeof(buf), fmt: "_uid.%u" , uid); |
102 | uid_keyring_r = keyring_search(keyring: make_key_ref(key: reg_keyring, possession: true), |
103 | type: &key_type_keyring, description: buf, recurse: false); |
104 | kdebug("_uid %p" , uid_keyring_r); |
105 | if (uid_keyring_r == ERR_PTR(error: -EAGAIN)) { |
106 | uid_keyring = keyring_alloc(description: buf, uid: cred->user->uid, INVALID_GID, |
107 | cred, perm: user_keyring_perm, |
108 | KEY_ALLOC_UID_KEYRING | |
109 | KEY_ALLOC_IN_QUOTA, |
110 | NULL, dest: reg_keyring); |
111 | if (IS_ERR(ptr: uid_keyring)) { |
112 | ret = PTR_ERR(ptr: uid_keyring); |
113 | goto error; |
114 | } |
115 | } else if (IS_ERR(ptr: uid_keyring_r)) { |
116 | ret = PTR_ERR(ptr: uid_keyring_r); |
117 | goto error; |
118 | } else { |
119 | uid_keyring = key_ref_to_ptr(key_ref: uid_keyring_r); |
120 | } |
121 | |
122 | /* Get a default session keyring (which might also exist already) */ |
123 | snprintf(buf, size: sizeof(buf), fmt: "_uid_ses.%u" , uid); |
124 | session_keyring_r = keyring_search(keyring: make_key_ref(key: reg_keyring, possession: true), |
125 | type: &key_type_keyring, description: buf, recurse: false); |
126 | kdebug("_uid_ses %p" , session_keyring_r); |
127 | if (session_keyring_r == ERR_PTR(error: -EAGAIN)) { |
128 | session_keyring = keyring_alloc(description: buf, uid: cred->user->uid, INVALID_GID, |
129 | cred, perm: user_keyring_perm, |
130 | KEY_ALLOC_UID_KEYRING | |
131 | KEY_ALLOC_IN_QUOTA, |
132 | NULL, NULL); |
133 | if (IS_ERR(ptr: session_keyring)) { |
134 | ret = PTR_ERR(ptr: session_keyring); |
135 | goto error_release; |
136 | } |
137 | |
138 | /* We install a link from the user session keyring to |
139 | * the user keyring. |
140 | */ |
141 | ret = key_link(keyring: session_keyring, key: uid_keyring); |
142 | if (ret < 0) |
143 | goto error_release_session; |
144 | |
145 | /* And only then link the user-session keyring to the |
146 | * register. |
147 | */ |
148 | ret = key_link(keyring: reg_keyring, key: session_keyring); |
149 | if (ret < 0) |
150 | goto error_release_session; |
151 | } else if (IS_ERR(ptr: session_keyring_r)) { |
152 | ret = PTR_ERR(ptr: session_keyring_r); |
153 | goto error_release; |
154 | } else { |
155 | session_keyring = key_ref_to_ptr(key_ref: session_keyring_r); |
156 | } |
157 | |
158 | up_write(sem: &user_ns->keyring_sem); |
159 | |
160 | if (_user_session_keyring) |
161 | *_user_session_keyring = session_keyring; |
162 | else |
163 | key_put(key: session_keyring); |
164 | if (_user_keyring) |
165 | *_user_keyring = uid_keyring; |
166 | else |
167 | key_put(key: uid_keyring); |
168 | kleave(" = 0" ); |
169 | return 0; |
170 | |
171 | error_release_session: |
172 | key_put(key: session_keyring); |
173 | error_release: |
174 | key_put(key: uid_keyring); |
175 | error: |
176 | up_write(sem: &user_ns->keyring_sem); |
177 | kleave(" = %d" , ret); |
178 | return ret; |
179 | } |
180 | |
181 | /* |
182 | * Get the user session keyring if it exists, but don't create it if it |
183 | * doesn't. |
184 | */ |
185 | struct key *get_user_session_keyring_rcu(const struct cred *cred) |
186 | { |
187 | struct key *reg_keyring = READ_ONCE(cred->user_ns->user_keyring_register); |
188 | key_ref_t session_keyring_r; |
189 | char buf[20]; |
190 | |
191 | struct keyring_search_context ctx = { |
192 | .index_key.type = &key_type_keyring, |
193 | .index_key.description = buf, |
194 | .cred = cred, |
195 | .match_data.cmp = key_default_cmp, |
196 | .match_data.raw_data = buf, |
197 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
198 | .flags = KEYRING_SEARCH_DO_STATE_CHECK, |
199 | }; |
200 | |
201 | if (!reg_keyring) |
202 | return NULL; |
203 | |
204 | ctx.index_key.desc_len = snprintf(buf, size: sizeof(buf), fmt: "_uid_ses.%u" , |
205 | from_kuid(to: cred->user_ns, |
206 | uid: cred->user->uid)); |
207 | |
208 | session_keyring_r = keyring_search_rcu(keyring_ref: make_key_ref(key: reg_keyring, possession: true), |
209 | ctx: &ctx); |
210 | if (IS_ERR(ptr: session_keyring_r)) |
211 | return NULL; |
212 | return key_ref_to_ptr(key_ref: session_keyring_r); |
213 | } |
214 | |
215 | /* |
216 | * Install a thread keyring to the given credentials struct if it didn't have |
217 | * one already. This is allowed to overrun the quota. |
218 | * |
219 | * Return: 0 if a thread keyring is now present; -errno on failure. |
220 | */ |
221 | int install_thread_keyring_to_cred(struct cred *new) |
222 | { |
223 | struct key *keyring; |
224 | |
225 | if (new->thread_keyring) |
226 | return 0; |
227 | |
228 | keyring = keyring_alloc(description: "_tid" , uid: new->uid, gid: new->gid, cred: new, |
229 | KEY_POS_ALL | KEY_USR_VIEW, |
230 | KEY_ALLOC_QUOTA_OVERRUN, |
231 | NULL, NULL); |
232 | if (IS_ERR(ptr: keyring)) |
233 | return PTR_ERR(ptr: keyring); |
234 | |
235 | new->thread_keyring = keyring; |
236 | return 0; |
237 | } |
238 | |
239 | /* |
240 | * Install a thread keyring to the current task if it didn't have one already. |
241 | * |
242 | * Return: 0 if a thread keyring is now present; -errno on failure. |
243 | */ |
244 | static int install_thread_keyring(void) |
245 | { |
246 | struct cred *new; |
247 | int ret; |
248 | |
249 | new = prepare_creds(); |
250 | if (!new) |
251 | return -ENOMEM; |
252 | |
253 | ret = install_thread_keyring_to_cred(new); |
254 | if (ret < 0) { |
255 | abort_creds(new); |
256 | return ret; |
257 | } |
258 | |
259 | return commit_creds(new); |
260 | } |
261 | |
262 | /* |
263 | * Install a process keyring to the given credentials struct if it didn't have |
264 | * one already. This is allowed to overrun the quota. |
265 | * |
266 | * Return: 0 if a process keyring is now present; -errno on failure. |
267 | */ |
268 | int install_process_keyring_to_cred(struct cred *new) |
269 | { |
270 | struct key *keyring; |
271 | |
272 | if (new->process_keyring) |
273 | return 0; |
274 | |
275 | keyring = keyring_alloc(description: "_pid" , uid: new->uid, gid: new->gid, cred: new, |
276 | KEY_POS_ALL | KEY_USR_VIEW, |
277 | KEY_ALLOC_QUOTA_OVERRUN, |
278 | NULL, NULL); |
279 | if (IS_ERR(ptr: keyring)) |
280 | return PTR_ERR(ptr: keyring); |
281 | |
282 | new->process_keyring = keyring; |
283 | return 0; |
284 | } |
285 | |
286 | /* |
287 | * Install a process keyring to the current task if it didn't have one already. |
288 | * |
289 | * Return: 0 if a process keyring is now present; -errno on failure. |
290 | */ |
291 | static int install_process_keyring(void) |
292 | { |
293 | struct cred *new; |
294 | int ret; |
295 | |
296 | new = prepare_creds(); |
297 | if (!new) |
298 | return -ENOMEM; |
299 | |
300 | ret = install_process_keyring_to_cred(new); |
301 | if (ret < 0) { |
302 | abort_creds(new); |
303 | return ret; |
304 | } |
305 | |
306 | return commit_creds(new); |
307 | } |
308 | |
309 | /* |
310 | * Install the given keyring as the session keyring of the given credentials |
311 | * struct, replacing the existing one if any. If the given keyring is NULL, |
312 | * then install a new anonymous session keyring. |
313 | * @cred can not be in use by any task yet. |
314 | * |
315 | * Return: 0 on success; -errno on failure. |
316 | */ |
317 | int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) |
318 | { |
319 | unsigned long flags; |
320 | struct key *old; |
321 | |
322 | might_sleep(); |
323 | |
324 | /* create an empty session keyring */ |
325 | if (!keyring) { |
326 | flags = KEY_ALLOC_QUOTA_OVERRUN; |
327 | if (cred->session_keyring) |
328 | flags = KEY_ALLOC_IN_QUOTA; |
329 | |
330 | keyring = keyring_alloc(description: "_ses" , uid: cred->uid, gid: cred->gid, cred, |
331 | KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, |
332 | flags, NULL, NULL); |
333 | if (IS_ERR(ptr: keyring)) |
334 | return PTR_ERR(ptr: keyring); |
335 | } else { |
336 | __key_get(key: keyring); |
337 | } |
338 | |
339 | /* install the keyring */ |
340 | old = cred->session_keyring; |
341 | cred->session_keyring = keyring; |
342 | |
343 | if (old) |
344 | key_put(key: old); |
345 | |
346 | return 0; |
347 | } |
348 | |
349 | /* |
350 | * Install the given keyring as the session keyring of the current task, |
351 | * replacing the existing one if any. If the given keyring is NULL, then |
352 | * install a new anonymous session keyring. |
353 | * |
354 | * Return: 0 on success; -errno on failure. |
355 | */ |
356 | static int install_session_keyring(struct key *keyring) |
357 | { |
358 | struct cred *new; |
359 | int ret; |
360 | |
361 | new = prepare_creds(); |
362 | if (!new) |
363 | return -ENOMEM; |
364 | |
365 | ret = install_session_keyring_to_cred(cred: new, keyring); |
366 | if (ret < 0) { |
367 | abort_creds(new); |
368 | return ret; |
369 | } |
370 | |
371 | return commit_creds(new); |
372 | } |
373 | |
374 | /* |
375 | * Handle the fsuid changing. |
376 | */ |
377 | void key_fsuid_changed(struct cred *new_cred) |
378 | { |
379 | /* update the ownership of the thread keyring */ |
380 | if (new_cred->thread_keyring) { |
381 | down_write(sem: &new_cred->thread_keyring->sem); |
382 | new_cred->thread_keyring->uid = new_cred->fsuid; |
383 | up_write(sem: &new_cred->thread_keyring->sem); |
384 | } |
385 | } |
386 | |
387 | /* |
388 | * Handle the fsgid changing. |
389 | */ |
390 | void key_fsgid_changed(struct cred *new_cred) |
391 | { |
392 | /* update the ownership of the thread keyring */ |
393 | if (new_cred->thread_keyring) { |
394 | down_write(sem: &new_cred->thread_keyring->sem); |
395 | new_cred->thread_keyring->gid = new_cred->fsgid; |
396 | up_write(sem: &new_cred->thread_keyring->sem); |
397 | } |
398 | } |
399 | |
400 | /* |
401 | * Search the process keyrings attached to the supplied cred for the first |
402 | * matching key under RCU conditions (the caller must be holding the RCU read |
403 | * lock). |
404 | * |
405 | * The search criteria are the type and the match function. The description is |
406 | * given to the match function as a parameter, but doesn't otherwise influence |
407 | * the search. Typically the match function will compare the description |
408 | * parameter to the key's description. |
409 | * |
410 | * This can only search keyrings that grant Search permission to the supplied |
411 | * credentials. Keyrings linked to searched keyrings will also be searched if |
412 | * they grant Search permission too. Keys can only be found if they grant |
413 | * Search permission to the credentials. |
414 | * |
415 | * Returns a pointer to the key with the key usage count incremented if |
416 | * successful, -EAGAIN if we didn't find any matching key or -ENOKEY if we only |
417 | * matched negative keys. |
418 | * |
419 | * In the case of a successful return, the possession attribute is set on the |
420 | * returned key reference. |
421 | */ |
422 | key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx) |
423 | { |
424 | struct key *user_session; |
425 | key_ref_t key_ref, ret, err; |
426 | const struct cred *cred = ctx->cred; |
427 | |
428 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were |
429 | * searchable, but we failed to find a key or we found a negative key; |
430 | * otherwise we want to return a sample error (probably -EACCES) if |
431 | * none of the keyrings were searchable |
432 | * |
433 | * in terms of priority: success > -ENOKEY > -EAGAIN > other error |
434 | */ |
435 | key_ref = NULL; |
436 | ret = NULL; |
437 | err = ERR_PTR(error: -EAGAIN); |
438 | |
439 | /* search the thread keyring first */ |
440 | if (cred->thread_keyring) { |
441 | key_ref = keyring_search_rcu( |
442 | keyring_ref: make_key_ref(key: cred->thread_keyring, possession: 1), ctx); |
443 | if (!IS_ERR(ptr: key_ref)) |
444 | goto found; |
445 | |
446 | switch (PTR_ERR(ptr: key_ref)) { |
447 | case -EAGAIN: /* no key */ |
448 | case -ENOKEY: /* negative key */ |
449 | ret = key_ref; |
450 | break; |
451 | default: |
452 | err = key_ref; |
453 | break; |
454 | } |
455 | } |
456 | |
457 | /* search the process keyring second */ |
458 | if (cred->process_keyring) { |
459 | key_ref = keyring_search_rcu( |
460 | keyring_ref: make_key_ref(key: cred->process_keyring, possession: 1), ctx); |
461 | if (!IS_ERR(ptr: key_ref)) |
462 | goto found; |
463 | |
464 | switch (PTR_ERR(ptr: key_ref)) { |
465 | case -EAGAIN: /* no key */ |
466 | if (ret) |
467 | break; |
468 | fallthrough; |
469 | case -ENOKEY: /* negative key */ |
470 | ret = key_ref; |
471 | break; |
472 | default: |
473 | err = key_ref; |
474 | break; |
475 | } |
476 | } |
477 | |
478 | /* search the session keyring */ |
479 | if (cred->session_keyring) { |
480 | key_ref = keyring_search_rcu( |
481 | keyring_ref: make_key_ref(key: cred->session_keyring, possession: 1), ctx); |
482 | |
483 | if (!IS_ERR(ptr: key_ref)) |
484 | goto found; |
485 | |
486 | switch (PTR_ERR(ptr: key_ref)) { |
487 | case -EAGAIN: /* no key */ |
488 | if (ret) |
489 | break; |
490 | fallthrough; |
491 | case -ENOKEY: /* negative key */ |
492 | ret = key_ref; |
493 | break; |
494 | default: |
495 | err = key_ref; |
496 | break; |
497 | } |
498 | } |
499 | /* or search the user-session keyring */ |
500 | else if ((user_session = get_user_session_keyring_rcu(cred))) { |
501 | key_ref = keyring_search_rcu(keyring_ref: make_key_ref(key: user_session, possession: 1), |
502 | ctx); |
503 | key_put(key: user_session); |
504 | |
505 | if (!IS_ERR(ptr: key_ref)) |
506 | goto found; |
507 | |
508 | switch (PTR_ERR(ptr: key_ref)) { |
509 | case -EAGAIN: /* no key */ |
510 | if (ret) |
511 | break; |
512 | fallthrough; |
513 | case -ENOKEY: /* negative key */ |
514 | ret = key_ref; |
515 | break; |
516 | default: |
517 | err = key_ref; |
518 | break; |
519 | } |
520 | } |
521 | |
522 | /* no key - decide on the error we're going to go for */ |
523 | key_ref = ret ? ret : err; |
524 | |
525 | found: |
526 | return key_ref; |
527 | } |
528 | |
529 | /* |
530 | * Search the process keyrings attached to the supplied cred for the first |
531 | * matching key in the manner of search_my_process_keyrings(), but also search |
532 | * the keys attached to the assumed authorisation key using its credentials if |
533 | * one is available. |
534 | * |
535 | * The caller must be holding the RCU read lock. |
536 | * |
537 | * Return same as search_cred_keyrings_rcu(). |
538 | */ |
539 | key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx) |
540 | { |
541 | struct request_key_auth *rka; |
542 | key_ref_t key_ref, ret = ERR_PTR(error: -EACCES), err; |
543 | |
544 | key_ref = search_cred_keyrings_rcu(ctx); |
545 | if (!IS_ERR(ptr: key_ref)) |
546 | goto found; |
547 | err = key_ref; |
548 | |
549 | /* if this process has an instantiation authorisation key, then we also |
550 | * search the keyrings of the process mentioned there |
551 | * - we don't permit access to request_key auth keys via this method |
552 | */ |
553 | if (ctx->cred->request_key_auth && |
554 | ctx->cred == current_cred() && |
555 | ctx->index_key.type != &key_type_request_key_auth |
556 | ) { |
557 | const struct cred *cred = ctx->cred; |
558 | |
559 | if (key_validate(key: cred->request_key_auth) == 0) { |
560 | rka = ctx->cred->request_key_auth->payload.data[0]; |
561 | |
562 | //// was search_process_keyrings() [ie. recursive] |
563 | ctx->cred = rka->cred; |
564 | key_ref = search_cred_keyrings_rcu(ctx); |
565 | ctx->cred = cred; |
566 | |
567 | if (!IS_ERR(ptr: key_ref)) |
568 | goto found; |
569 | ret = key_ref; |
570 | } |
571 | } |
572 | |
573 | /* no key - decide on the error we're going to go for */ |
574 | if (err == ERR_PTR(error: -ENOKEY) || ret == ERR_PTR(error: -ENOKEY)) |
575 | key_ref = ERR_PTR(error: -ENOKEY); |
576 | else if (err == ERR_PTR(error: -EACCES)) |
577 | key_ref = ret; |
578 | else |
579 | key_ref = err; |
580 | |
581 | found: |
582 | return key_ref; |
583 | } |
584 | /* |
585 | * See if the key we're looking at is the target key. |
586 | */ |
587 | bool lookup_user_key_possessed(const struct key *key, |
588 | const struct key_match_data *match_data) |
589 | { |
590 | return key == match_data->raw_data; |
591 | } |
592 | |
593 | /* |
594 | * Look up a key ID given us by userspace with a given permissions mask to get |
595 | * the key it refers to. |
596 | * |
597 | * Flags can be passed to request that special keyrings be created if referred |
598 | * to directly, to permit partially constructed keys to be found and to skip |
599 | * validity and permission checks on the found key. |
600 | * |
601 | * Returns a pointer to the key with an incremented usage count if successful; |
602 | * -EINVAL if the key ID is invalid; -ENOKEY if the key ID does not correspond |
603 | * to a key or the best found key was a negative key; -EKEYREVOKED or |
604 | * -EKEYEXPIRED if the best found key was revoked or expired; -EACCES if the |
605 | * found key doesn't grant the requested permit or the LSM denied access to it; |
606 | * or -ENOMEM if a special keyring couldn't be created. |
607 | * |
608 | * In the case of a successful return, the possession attribute is set on the |
609 | * returned key reference. |
610 | */ |
611 | key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, |
612 | enum key_need_perm need_perm) |
613 | { |
614 | struct keyring_search_context ctx = { |
615 | .match_data.cmp = lookup_user_key_possessed, |
616 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
617 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | |
618 | KEYRING_SEARCH_RECURSE), |
619 | }; |
620 | struct request_key_auth *rka; |
621 | struct key *key, *user_session; |
622 | key_ref_t key_ref, skey_ref; |
623 | int ret; |
624 | |
625 | try_again: |
626 | ctx.cred = get_current_cred(); |
627 | key_ref = ERR_PTR(error: -ENOKEY); |
628 | |
629 | switch (id) { |
630 | case KEY_SPEC_THREAD_KEYRING: |
631 | if (!ctx.cred->thread_keyring) { |
632 | if (!(lflags & KEY_LOOKUP_CREATE)) |
633 | goto error; |
634 | |
635 | ret = install_thread_keyring(); |
636 | if (ret < 0) { |
637 | key_ref = ERR_PTR(error: ret); |
638 | goto error; |
639 | } |
640 | goto reget_creds; |
641 | } |
642 | |
643 | key = ctx.cred->thread_keyring; |
644 | __key_get(key); |
645 | key_ref = make_key_ref(key, possession: 1); |
646 | break; |
647 | |
648 | case KEY_SPEC_PROCESS_KEYRING: |
649 | if (!ctx.cred->process_keyring) { |
650 | if (!(lflags & KEY_LOOKUP_CREATE)) |
651 | goto error; |
652 | |
653 | ret = install_process_keyring(); |
654 | if (ret < 0) { |
655 | key_ref = ERR_PTR(error: ret); |
656 | goto error; |
657 | } |
658 | goto reget_creds; |
659 | } |
660 | |
661 | key = ctx.cred->process_keyring; |
662 | __key_get(key); |
663 | key_ref = make_key_ref(key, possession: 1); |
664 | break; |
665 | |
666 | case KEY_SPEC_SESSION_KEYRING: |
667 | if (!ctx.cred->session_keyring) { |
668 | /* always install a session keyring upon access if one |
669 | * doesn't exist yet */ |
670 | ret = look_up_user_keyrings(NULL, user_session_keyring: &user_session); |
671 | if (ret < 0) |
672 | goto error; |
673 | if (lflags & KEY_LOOKUP_CREATE) |
674 | ret = join_session_keyring(NULL); |
675 | else |
676 | ret = install_session_keyring(keyring: user_session); |
677 | |
678 | key_put(key: user_session); |
679 | if (ret < 0) |
680 | goto error; |
681 | goto reget_creds; |
682 | } else if (test_bit(KEY_FLAG_UID_KEYRING, |
683 | &ctx.cred->session_keyring->flags) && |
684 | lflags & KEY_LOOKUP_CREATE) { |
685 | ret = join_session_keyring(NULL); |
686 | if (ret < 0) |
687 | goto error; |
688 | goto reget_creds; |
689 | } |
690 | |
691 | key = ctx.cred->session_keyring; |
692 | __key_get(key); |
693 | key_ref = make_key_ref(key, possession: 1); |
694 | break; |
695 | |
696 | case KEY_SPEC_USER_KEYRING: |
697 | ret = look_up_user_keyrings(user_keyring: &key, NULL); |
698 | if (ret < 0) |
699 | goto error; |
700 | key_ref = make_key_ref(key, possession: 1); |
701 | break; |
702 | |
703 | case KEY_SPEC_USER_SESSION_KEYRING: |
704 | ret = look_up_user_keyrings(NULL, user_session_keyring: &key); |
705 | if (ret < 0) |
706 | goto error; |
707 | key_ref = make_key_ref(key, possession: 1); |
708 | break; |
709 | |
710 | case KEY_SPEC_GROUP_KEYRING: |
711 | /* group keyrings are not yet supported */ |
712 | key_ref = ERR_PTR(error: -EINVAL); |
713 | goto error; |
714 | |
715 | case KEY_SPEC_REQKEY_AUTH_KEY: |
716 | key = ctx.cred->request_key_auth; |
717 | if (!key) |
718 | goto error; |
719 | |
720 | __key_get(key); |
721 | key_ref = make_key_ref(key, possession: 1); |
722 | break; |
723 | |
724 | case KEY_SPEC_REQUESTOR_KEYRING: |
725 | if (!ctx.cred->request_key_auth) |
726 | goto error; |
727 | |
728 | down_read(sem: &ctx.cred->request_key_auth->sem); |
729 | if (test_bit(KEY_FLAG_REVOKED, |
730 | &ctx.cred->request_key_auth->flags)) { |
731 | key_ref = ERR_PTR(error: -EKEYREVOKED); |
732 | key = NULL; |
733 | } else { |
734 | rka = ctx.cred->request_key_auth->payload.data[0]; |
735 | key = rka->dest_keyring; |
736 | __key_get(key); |
737 | } |
738 | up_read(sem: &ctx.cred->request_key_auth->sem); |
739 | if (!key) |
740 | goto error; |
741 | key_ref = make_key_ref(key, possession: 1); |
742 | break; |
743 | |
744 | default: |
745 | key_ref = ERR_PTR(error: -EINVAL); |
746 | if (id < 1) |
747 | goto error; |
748 | |
749 | key = key_lookup(id); |
750 | if (IS_ERR(ptr: key)) { |
751 | key_ref = ERR_CAST(ptr: key); |
752 | goto error; |
753 | } |
754 | |
755 | key_ref = make_key_ref(key, possession: 0); |
756 | |
757 | /* check to see if we possess the key */ |
758 | ctx.index_key = key->index_key; |
759 | ctx.match_data.raw_data = key; |
760 | kdebug("check possessed" ); |
761 | rcu_read_lock(); |
762 | skey_ref = search_process_keyrings_rcu(ctx: &ctx); |
763 | rcu_read_unlock(); |
764 | kdebug("possessed=%p" , skey_ref); |
765 | |
766 | if (!IS_ERR(ptr: skey_ref)) { |
767 | key_put(key); |
768 | key_ref = skey_ref; |
769 | } |
770 | |
771 | break; |
772 | } |
773 | |
774 | /* unlink does not use the nominated key in any way, so can skip all |
775 | * the permission checks as it is only concerned with the keyring */ |
776 | if (need_perm != KEY_NEED_UNLINK) { |
777 | if (!(lflags & KEY_LOOKUP_PARTIAL)) { |
778 | ret = wait_for_key_construction(key, intr: true); |
779 | switch (ret) { |
780 | case -ERESTARTSYS: |
781 | goto invalid_key; |
782 | default: |
783 | if (need_perm != KEY_AUTHTOKEN_OVERRIDE && |
784 | need_perm != KEY_DEFER_PERM_CHECK) |
785 | goto invalid_key; |
786 | break; |
787 | case 0: |
788 | break; |
789 | } |
790 | } else if (need_perm != KEY_DEFER_PERM_CHECK) { |
791 | ret = key_validate(key); |
792 | if (ret < 0) |
793 | goto invalid_key; |
794 | } |
795 | |
796 | ret = -EIO; |
797 | if (!(lflags & KEY_LOOKUP_PARTIAL) && |
798 | key_read_state(key) == KEY_IS_UNINSTANTIATED) |
799 | goto invalid_key; |
800 | } |
801 | |
802 | /* check the permissions */ |
803 | ret = key_task_permission(key_ref, cred: ctx.cred, need_perm); |
804 | if (ret < 0) |
805 | goto invalid_key; |
806 | |
807 | key->last_used_at = ktime_get_real_seconds(); |
808 | |
809 | error: |
810 | put_cred(cred: ctx.cred); |
811 | return key_ref; |
812 | |
813 | invalid_key: |
814 | key_ref_put(key_ref); |
815 | key_ref = ERR_PTR(error: ret); |
816 | goto error; |
817 | |
818 | /* if we attempted to install a keyring, then it may have caused new |
819 | * creds to be installed */ |
820 | reget_creds: |
821 | put_cred(cred: ctx.cred); |
822 | goto try_again; |
823 | } |
824 | EXPORT_SYMBOL(lookup_user_key); |
825 | |
826 | /* |
827 | * Join the named keyring as the session keyring if possible else attempt to |
828 | * create a new one of that name and join that. |
829 | * |
830 | * If the name is NULL, an empty anonymous keyring will be installed as the |
831 | * session keyring. |
832 | * |
833 | * Named session keyrings are joined with a semaphore held to prevent the |
834 | * keyrings from going away whilst the attempt is made to going them and also |
835 | * to prevent a race in creating compatible session keyrings. |
836 | */ |
837 | long join_session_keyring(const char *name) |
838 | { |
839 | const struct cred *old; |
840 | struct cred *new; |
841 | struct key *keyring; |
842 | long ret, serial; |
843 | |
844 | new = prepare_creds(); |
845 | if (!new) |
846 | return -ENOMEM; |
847 | old = current_cred(); |
848 | |
849 | /* if no name is provided, install an anonymous keyring */ |
850 | if (!name) { |
851 | ret = install_session_keyring_to_cred(cred: new, NULL); |
852 | if (ret < 0) |
853 | goto error; |
854 | |
855 | serial = new->session_keyring->serial; |
856 | ret = commit_creds(new); |
857 | if (ret == 0) |
858 | ret = serial; |
859 | goto okay; |
860 | } |
861 | |
862 | /* allow the user to join or create a named keyring */ |
863 | mutex_lock(&key_session_mutex); |
864 | |
865 | /* look for an existing keyring of this name */ |
866 | keyring = find_keyring_by_name(name, uid_keyring: false); |
867 | if (PTR_ERR(ptr: keyring) == -ENOKEY) { |
868 | /* not found - try and create a new one */ |
869 | keyring = keyring_alloc( |
870 | description: name, uid: old->uid, gid: old->gid, cred: old, |
871 | KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK, |
872 | KEY_ALLOC_IN_QUOTA, NULL, NULL); |
873 | if (IS_ERR(ptr: keyring)) { |
874 | ret = PTR_ERR(ptr: keyring); |
875 | goto error2; |
876 | } |
877 | } else if (IS_ERR(ptr: keyring)) { |
878 | ret = PTR_ERR(ptr: keyring); |
879 | goto error2; |
880 | } else if (keyring == new->session_keyring) { |
881 | ret = 0; |
882 | goto error3; |
883 | } |
884 | |
885 | /* we've got a keyring - now to install it */ |
886 | ret = install_session_keyring_to_cred(cred: new, keyring); |
887 | if (ret < 0) |
888 | goto error3; |
889 | |
890 | commit_creds(new); |
891 | mutex_unlock(lock: &key_session_mutex); |
892 | |
893 | ret = keyring->serial; |
894 | key_put(key: keyring); |
895 | okay: |
896 | return ret; |
897 | |
898 | error3: |
899 | key_put(key: keyring); |
900 | error2: |
901 | mutex_unlock(lock: &key_session_mutex); |
902 | error: |
903 | abort_creds(new); |
904 | return ret; |
905 | } |
906 | |
907 | /* |
908 | * Replace a process's session keyring on behalf of one of its children when |
909 | * the target process is about to resume userspace execution. |
910 | */ |
911 | void key_change_session_keyring(struct callback_head *twork) |
912 | { |
913 | const struct cred *old = current_cred(); |
914 | struct cred *new = container_of(twork, struct cred, rcu); |
915 | |
916 | if (unlikely(current->flags & PF_EXITING)) { |
917 | put_cred(cred: new); |
918 | return; |
919 | } |
920 | |
921 | /* If get_ucounts fails more bits are needed in the refcount */ |
922 | if (unlikely(!get_ucounts(old->ucounts))) { |
923 | WARN_ONCE(1, "In %s get_ucounts failed\n" , __func__); |
924 | put_cred(cred: new); |
925 | return; |
926 | } |
927 | |
928 | new-> uid = old-> uid; |
929 | new-> euid = old-> euid; |
930 | new-> suid = old-> suid; |
931 | new->fsuid = old->fsuid; |
932 | new-> gid = old-> gid; |
933 | new-> egid = old-> egid; |
934 | new-> sgid = old-> sgid; |
935 | new->fsgid = old->fsgid; |
936 | new->user = get_uid(u: old->user); |
937 | new->ucounts = old->ucounts; |
938 | new->user_ns = get_user_ns(ns: old->user_ns); |
939 | new->group_info = get_group_info(gi: old->group_info); |
940 | |
941 | new->securebits = old->securebits; |
942 | new->cap_inheritable = old->cap_inheritable; |
943 | new->cap_permitted = old->cap_permitted; |
944 | new->cap_effective = old->cap_effective; |
945 | new->cap_ambient = old->cap_ambient; |
946 | new->cap_bset = old->cap_bset; |
947 | |
948 | new->jit_keyring = old->jit_keyring; |
949 | new->thread_keyring = key_get(key: old->thread_keyring); |
950 | new->process_keyring = key_get(key: old->process_keyring); |
951 | |
952 | security_transfer_creds(new, old); |
953 | |
954 | commit_creds(new); |
955 | } |
956 | |
957 | /* |
958 | * Make sure that root's user and user-session keyrings exist. |
959 | */ |
960 | static int __init init_root_keyring(void) |
961 | { |
962 | return look_up_user_keyrings(NULL, NULL); |
963 | } |
964 | |
965 | late_initcall(init_root_keyring); |
966 | |