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