OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [security/] [keys/] [process_keys.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* process_keys.c: management of a process's keyrings
2
 *
3
 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4
 * Written by David Howells (dhowells@redhat.com)
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/slab.h>
16
#include <linux/keyctl.h>
17
#include <linux/fs.h>
18
#include <linux/err.h>
19
#include <linux/mutex.h>
20
#include <asm/uaccess.h>
21
#include "internal.h"
22
 
23
/* session keyring create vs join semaphore */
24
static DEFINE_MUTEX(key_session_mutex);
25
 
26
/* the root user's tracking struct */
27
struct key_user root_key_user = {
28
        .usage          = ATOMIC_INIT(3),
29
        .cons_lock      = __MUTEX_INITIALIZER(root_key_user.cons_lock),
30
        .lock           = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
31
        .nkeys          = ATOMIC_INIT(2),
32
        .nikeys         = ATOMIC_INIT(2),
33
        .uid            = 0,
34
};
35
 
36
/* the root user's UID keyring */
37
struct key root_user_keyring = {
38
        .usage          = ATOMIC_INIT(1),
39
        .serial         = 2,
40
        .type           = &key_type_keyring,
41
        .user           = &root_key_user,
42
        .sem            = __RWSEM_INITIALIZER(root_user_keyring.sem),
43
        .perm           = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
44
        .flags          = 1 << KEY_FLAG_INSTANTIATED,
45
        .description    = "_uid.0",
46
#ifdef KEY_DEBUGGING
47
        .magic          = KEY_DEBUG_MAGIC,
48
#endif
49
};
50
 
51
/* the root user's default session keyring */
52
struct key root_session_keyring = {
53
        .usage          = ATOMIC_INIT(1),
54
        .serial         = 1,
55
        .type           = &key_type_keyring,
56
        .user           = &root_key_user,
57
        .sem            = __RWSEM_INITIALIZER(root_session_keyring.sem),
58
        .perm           = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
59
        .flags          = 1 << KEY_FLAG_INSTANTIATED,
60
        .description    = "_uid_ses.0",
61
#ifdef KEY_DEBUGGING
62
        .magic          = KEY_DEBUG_MAGIC,
63
#endif
64
};
65
 
66
/*****************************************************************************/
67
/*
68
 * allocate the keyrings to be associated with a UID
69
 */
70
int alloc_uid_keyring(struct user_struct *user,
71
                      struct task_struct *ctx)
72
{
73
        struct key *uid_keyring, *session_keyring;
74
        char buf[20];
75
        int ret;
76
 
77
        /* concoct a default session keyring */
78
        sprintf(buf, "_uid_ses.%u", user->uid);
79
 
80
        session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx,
81
                                        KEY_ALLOC_IN_QUOTA, NULL);
82
        if (IS_ERR(session_keyring)) {
83
                ret = PTR_ERR(session_keyring);
84
                goto error;
85
        }
86
 
87
        /* and a UID specific keyring, pointed to by the default session
88
         * keyring */
89
        sprintf(buf, "_uid.%u", user->uid);
90
 
91
        uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx,
92
                                    KEY_ALLOC_IN_QUOTA, session_keyring);
93
        if (IS_ERR(uid_keyring)) {
94
                key_put(session_keyring);
95
                ret = PTR_ERR(uid_keyring);
96
                goto error;
97
        }
98
 
99
        /* install the keyrings */
100
        user->uid_keyring = uid_keyring;
101
        user->session_keyring = session_keyring;
102
        ret = 0;
103
 
104
error:
105
        return ret;
106
 
107
} /* end alloc_uid_keyring() */
108
 
109
/*****************************************************************************/
110
/*
111
 * deal with the UID changing
112
 */
113
void switch_uid_keyring(struct user_struct *new_user)
114
{
115
#if 0 /* do nothing for now */
116
        struct key *old;
117
 
118
        /* switch to the new user's session keyring if we were running under
119
         * root's default session keyring */
120
        if (new_user->uid != 0 &&
121
            current->session_keyring == &root_session_keyring
122
            ) {
123
                atomic_inc(&new_user->session_keyring->usage);
124
 
125
                task_lock(current);
126
                old = current->session_keyring;
127
                current->session_keyring = new_user->session_keyring;
128
                task_unlock(current);
129
 
130
                key_put(old);
131
        }
132
#endif
133
 
134
} /* end switch_uid_keyring() */
135
 
136
/*****************************************************************************/
137
/*
138
 * install a fresh thread keyring, discarding the old one
139
 */
140
int install_thread_keyring(struct task_struct *tsk)
141
{
142
        struct key *keyring, *old;
143
        char buf[20];
144
        int ret;
145
 
146
        sprintf(buf, "_tid.%u", tsk->pid);
147
 
148
        keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
149
                                KEY_ALLOC_QUOTA_OVERRUN, NULL);
150
        if (IS_ERR(keyring)) {
151
                ret = PTR_ERR(keyring);
152
                goto error;
153
        }
154
 
155
        task_lock(tsk);
156
        old = tsk->thread_keyring;
157
        tsk->thread_keyring = keyring;
158
        task_unlock(tsk);
159
 
160
        ret = 0;
161
 
162
        key_put(old);
163
error:
164
        return ret;
165
 
166
} /* end install_thread_keyring() */
167
 
168
/*****************************************************************************/
169
/*
170
 * make sure a process keyring is installed
171
 */
172
int install_process_keyring(struct task_struct *tsk)
173
{
174
        struct key *keyring;
175
        char buf[20];
176
        int ret;
177
 
178
        might_sleep();
179
 
180
        if (!tsk->signal->process_keyring) {
181
                sprintf(buf, "_pid.%u", tsk->tgid);
182
 
183
                keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
184
                                        KEY_ALLOC_QUOTA_OVERRUN, NULL);
185
                if (IS_ERR(keyring)) {
186
                        ret = PTR_ERR(keyring);
187
                        goto error;
188
                }
189
 
190
                /* attach keyring */
191
                spin_lock_irq(&tsk->sighand->siglock);
192
                if (!tsk->signal->process_keyring) {
193
                        tsk->signal->process_keyring = keyring;
194
                        keyring = NULL;
195
                }
196
                spin_unlock_irq(&tsk->sighand->siglock);
197
 
198
                key_put(keyring);
199
        }
200
 
201
        ret = 0;
202
error:
203
        return ret;
204
 
205
} /* end install_process_keyring() */
206
 
207
/*****************************************************************************/
208
/*
209
 * install a session keyring, discarding the old one
210
 * - if a keyring is not supplied, an empty one is invented
211
 */
212
static int install_session_keyring(struct task_struct *tsk,
213
                                   struct key *keyring)
214
{
215
        unsigned long flags;
216
        struct key *old;
217
        char buf[20];
218
 
219
        might_sleep();
220
 
221
        /* create an empty session keyring */
222
        if (!keyring) {
223
                sprintf(buf, "_ses.%u", tsk->tgid);
224
 
225
                flags = KEY_ALLOC_QUOTA_OVERRUN;
226
                if (tsk->signal->session_keyring)
227
                        flags = KEY_ALLOC_IN_QUOTA;
228
 
229
                keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
230
                                        flags, NULL);
231
                if (IS_ERR(keyring))
232
                        return PTR_ERR(keyring);
233
        }
234
        else {
235
                atomic_inc(&keyring->usage);
236
        }
237
 
238
        /* install the keyring */
239
        spin_lock_irq(&tsk->sighand->siglock);
240
        old = tsk->signal->session_keyring;
241
        rcu_assign_pointer(tsk->signal->session_keyring, keyring);
242
        spin_unlock_irq(&tsk->sighand->siglock);
243
 
244
        /* we're using RCU on the pointer, but there's no point synchronising
245
         * on it if it didn't previously point to anything */
246
        if (old) {
247
                synchronize_rcu();
248
                key_put(old);
249
        }
250
 
251
        return 0;
252
 
253
} /* end install_session_keyring() */
254
 
255
/*****************************************************************************/
256
/*
257
 * copy the keys in a thread group for fork without CLONE_THREAD
258
 */
259
int copy_thread_group_keys(struct task_struct *tsk)
260
{
261
        key_check(current->thread_group->session_keyring);
262
        key_check(current->thread_group->process_keyring);
263
 
264
        /* no process keyring yet */
265
        tsk->signal->process_keyring = NULL;
266
 
267
        /* same session keyring */
268
        rcu_read_lock();
269
        tsk->signal->session_keyring =
270
                key_get(rcu_dereference(current->signal->session_keyring));
271
        rcu_read_unlock();
272
 
273
        return 0;
274
 
275
} /* end copy_thread_group_keys() */
276
 
277
/*****************************************************************************/
278
/*
279
 * copy the keys for fork
280
 */
281
int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
282
{
283
        key_check(tsk->thread_keyring);
284
        key_check(tsk->request_key_auth);
285
 
286
        /* no thread keyring yet */
287
        tsk->thread_keyring = NULL;
288
 
289
        /* copy the request_key() authorisation for this thread */
290
        key_get(tsk->request_key_auth);
291
 
292
        return 0;
293
 
294
} /* end copy_keys() */
295
 
296
/*****************************************************************************/
297
/*
298
 * dispose of thread group keys upon thread group destruction
299
 */
300
void exit_thread_group_keys(struct signal_struct *tg)
301
{
302
        key_put(tg->session_keyring);
303
        key_put(tg->process_keyring);
304
 
305
} /* end exit_thread_group_keys() */
306
 
307
/*****************************************************************************/
308
/*
309
 * dispose of per-thread keys upon thread exit
310
 */
311
void exit_keys(struct task_struct *tsk)
312
{
313
        key_put(tsk->thread_keyring);
314
        key_put(tsk->request_key_auth);
315
 
316
} /* end exit_keys() */
317
 
318
/*****************************************************************************/
319
/*
320
 * deal with execve()
321
 */
322
int exec_keys(struct task_struct *tsk)
323
{
324
        struct key *old;
325
 
326
        /* newly exec'd tasks don't get a thread keyring */
327
        task_lock(tsk);
328
        old = tsk->thread_keyring;
329
        tsk->thread_keyring = NULL;
330
        task_unlock(tsk);
331
 
332
        key_put(old);
333
 
334
        /* discard the process keyring from a newly exec'd task */
335
        spin_lock_irq(&tsk->sighand->siglock);
336
        old = tsk->signal->process_keyring;
337
        tsk->signal->process_keyring = NULL;
338
        spin_unlock_irq(&tsk->sighand->siglock);
339
 
340
        key_put(old);
341
 
342
        return 0;
343
 
344
} /* end exec_keys() */
345
 
346
/*****************************************************************************/
347
/*
348
 * deal with SUID programs
349
 * - we might want to make this invent a new session keyring
350
 */
351
int suid_keys(struct task_struct *tsk)
352
{
353
        return 0;
354
 
355
} /* end suid_keys() */
356
 
357
/*****************************************************************************/
358
/*
359
 * the filesystem user ID changed
360
 */
361
void key_fsuid_changed(struct task_struct *tsk)
362
{
363
        /* update the ownership of the thread keyring */
364
        if (tsk->thread_keyring) {
365
                down_write(&tsk->thread_keyring->sem);
366
                tsk->thread_keyring->uid = tsk->fsuid;
367
                up_write(&tsk->thread_keyring->sem);
368
        }
369
 
370
} /* end key_fsuid_changed() */
371
 
372
/*****************************************************************************/
373
/*
374
 * the filesystem group ID changed
375
 */
376
void key_fsgid_changed(struct task_struct *tsk)
377
{
378
        /* update the ownership of the thread keyring */
379
        if (tsk->thread_keyring) {
380
                down_write(&tsk->thread_keyring->sem);
381
                tsk->thread_keyring->gid = tsk->fsgid;
382
                up_write(&tsk->thread_keyring->sem);
383
        }
384
 
385
} /* end key_fsgid_changed() */
386
 
387
/*****************************************************************************/
388
/*
389
 * search the process keyrings for the first matching key
390
 * - we use the supplied match function to see if the description (or other
391
 *   feature of interest) matches
392
 * - we return -EAGAIN if we didn't find any matching key
393
 * - we return -ENOKEY if we found only negative matching keys
394
 */
395
key_ref_t search_process_keyrings(struct key_type *type,
396
                                  const void *description,
397
                                  key_match_func_t match,
398
                                  struct task_struct *context)
399
{
400
        struct request_key_auth *rka;
401
        key_ref_t key_ref, ret, err;
402
 
403
        might_sleep();
404
 
405
        /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
406
         * searchable, but we failed to find a key or we found a negative key;
407
         * otherwise we want to return a sample error (probably -EACCES) if
408
         * none of the keyrings were searchable
409
         *
410
         * in terms of priority: success > -ENOKEY > -EAGAIN > other error
411
         */
412
        key_ref = NULL;
413
        ret = NULL;
414
        err = ERR_PTR(-EAGAIN);
415
 
416
        /* search the thread keyring first */
417
        if (context->thread_keyring) {
418
                key_ref = keyring_search_aux(
419
                        make_key_ref(context->thread_keyring, 1),
420
                        context, type, description, match);
421
                if (!IS_ERR(key_ref))
422
                        goto found;
423
 
424
                switch (PTR_ERR(key_ref)) {
425
                case -EAGAIN: /* no key */
426
                        if (ret)
427
                                break;
428
                case -ENOKEY: /* negative key */
429
                        ret = key_ref;
430
                        break;
431
                default:
432
                        err = key_ref;
433
                        break;
434
                }
435
        }
436
 
437
        /* search the process keyring second */
438
        if (context->signal->process_keyring) {
439
                key_ref = keyring_search_aux(
440
                        make_key_ref(context->signal->process_keyring, 1),
441
                        context, type, description, match);
442
                if (!IS_ERR(key_ref))
443
                        goto found;
444
 
445
                switch (PTR_ERR(key_ref)) {
446
                case -EAGAIN: /* no key */
447
                        if (ret)
448
                                break;
449
                case -ENOKEY: /* negative key */
450
                        ret = key_ref;
451
                        break;
452
                default:
453
                        err = key_ref;
454
                        break;
455
                }
456
        }
457
 
458
        /* search the session keyring */
459
        if (context->signal->session_keyring) {
460
                rcu_read_lock();
461
                key_ref = keyring_search_aux(
462
                        make_key_ref(rcu_dereference(
463
                                             context->signal->session_keyring),
464
                                     1),
465
                        context, type, description, match);
466
                rcu_read_unlock();
467
 
468
                if (!IS_ERR(key_ref))
469
                        goto found;
470
 
471
                switch (PTR_ERR(key_ref)) {
472
                case -EAGAIN: /* no key */
473
                        if (ret)
474
                                break;
475
                case -ENOKEY: /* negative key */
476
                        ret = key_ref;
477
                        break;
478
                default:
479
                        err = key_ref;
480
                        break;
481
                }
482
        }
483
        /* or search the user-session keyring */
484
        else {
485
                key_ref = keyring_search_aux(
486
                        make_key_ref(context->user->session_keyring, 1),
487
                        context, type, description, match);
488
                if (!IS_ERR(key_ref))
489
                        goto found;
490
 
491
                switch (PTR_ERR(key_ref)) {
492
                case -EAGAIN: /* no key */
493
                        if (ret)
494
                                break;
495
                case -ENOKEY: /* negative key */
496
                        ret = key_ref;
497
                        break;
498
                default:
499
                        err = key_ref;
500
                        break;
501
                }
502
        }
503
 
504
        /* if this process has an instantiation authorisation key, then we also
505
         * search the keyrings of the process mentioned there
506
         * - we don't permit access to request_key auth keys via this method
507
         */
508
        if (context->request_key_auth &&
509
            context == current &&
510
            type != &key_type_request_key_auth
511
            ) {
512
                /* defend against the auth key being revoked */
513
                down_read(&context->request_key_auth->sem);
514
 
515
                if (key_validate(context->request_key_auth) == 0) {
516
                        rka = context->request_key_auth->payload.data;
517
 
518
                        key_ref = search_process_keyrings(type, description,
519
                                                          match, rka->context);
520
 
521
                        up_read(&context->request_key_auth->sem);
522
 
523
                        if (!IS_ERR(key_ref))
524
                                goto found;
525
 
526
                        switch (PTR_ERR(key_ref)) {
527
                        case -EAGAIN: /* no key */
528
                                if (ret)
529
                                        break;
530
                        case -ENOKEY: /* negative key */
531
                                ret = key_ref;
532
                                break;
533
                        default:
534
                                err = key_ref;
535
                                break;
536
                        }
537
                } else {
538
                        up_read(&context->request_key_auth->sem);
539
                }
540
        }
541
 
542
        /* no key - decide on the error we're going to go for */
543
        key_ref = ret ? ret : err;
544
 
545
found:
546
        return key_ref;
547
 
548
} /* end search_process_keyrings() */
549
 
550
/*****************************************************************************/
551
/*
552
 * see if the key we're looking at is the target key
553
 */
554
static int lookup_user_key_possessed(const struct key *key, const void *target)
555
{
556
        return key == target;
557
 
558
} /* end lookup_user_key_possessed() */
559
 
560
/*****************************************************************************/
561
/*
562
 * lookup a key given a key ID from userspace with a given permissions mask
563
 * - don't create special keyrings unless so requested
564
 * - partially constructed keys aren't found unless requested
565
 */
566
key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
567
                          int create, int partial, key_perm_t perm)
568
{
569
        key_ref_t key_ref, skey_ref;
570
        struct key *key;
571
        int ret;
572
 
573
        if (!context)
574
                context = current;
575
 
576
        key_ref = ERR_PTR(-ENOKEY);
577
 
578
        switch (id) {
579
        case KEY_SPEC_THREAD_KEYRING:
580
                if (!context->thread_keyring) {
581
                        if (!create)
582
                                goto error;
583
 
584
                        ret = install_thread_keyring(context);
585
                        if (ret < 0) {
586
                                key = ERR_PTR(ret);
587
                                goto error;
588
                        }
589
                }
590
 
591
                key = context->thread_keyring;
592
                atomic_inc(&key->usage);
593
                key_ref = make_key_ref(key, 1);
594
                break;
595
 
596
        case KEY_SPEC_PROCESS_KEYRING:
597
                if (!context->signal->process_keyring) {
598
                        if (!create)
599
                                goto error;
600
 
601
                        ret = install_process_keyring(context);
602
                        if (ret < 0) {
603
                                key = ERR_PTR(ret);
604
                                goto error;
605
                        }
606
                }
607
 
608
                key = context->signal->process_keyring;
609
                atomic_inc(&key->usage);
610
                key_ref = make_key_ref(key, 1);
611
                break;
612
 
613
        case KEY_SPEC_SESSION_KEYRING:
614
                if (!context->signal->session_keyring) {
615
                        /* always install a session keyring upon access if one
616
                         * doesn't exist yet */
617
                        ret = install_session_keyring(
618
                                context, context->user->session_keyring);
619
                        if (ret < 0)
620
                                goto error;
621
                }
622
 
623
                rcu_read_lock();
624
                key = rcu_dereference(context->signal->session_keyring);
625
                atomic_inc(&key->usage);
626
                rcu_read_unlock();
627
                key_ref = make_key_ref(key, 1);
628
                break;
629
 
630
        case KEY_SPEC_USER_KEYRING:
631
                key = context->user->uid_keyring;
632
                atomic_inc(&key->usage);
633
                key_ref = make_key_ref(key, 1);
634
                break;
635
 
636
        case KEY_SPEC_USER_SESSION_KEYRING:
637
                key = context->user->session_keyring;
638
                atomic_inc(&key->usage);
639
                key_ref = make_key_ref(key, 1);
640
                break;
641
 
642
        case KEY_SPEC_GROUP_KEYRING:
643
                /* group keyrings are not yet supported */
644
                key = ERR_PTR(-EINVAL);
645
                goto error;
646
 
647
        case KEY_SPEC_REQKEY_AUTH_KEY:
648
                key = context->request_key_auth;
649
                if (!key)
650
                        goto error;
651
 
652
                atomic_inc(&key->usage);
653
                key_ref = make_key_ref(key, 1);
654
                break;
655
 
656
        default:
657
                key_ref = ERR_PTR(-EINVAL);
658
                if (id < 1)
659
                        goto error;
660
 
661
                key = key_lookup(id);
662
                if (IS_ERR(key)) {
663
                        key_ref = ERR_PTR(PTR_ERR(key));
664
                        goto error;
665
                }
666
 
667
                key_ref = make_key_ref(key, 0);
668
 
669
                /* check to see if we possess the key */
670
                skey_ref = search_process_keyrings(key->type, key,
671
                                                   lookup_user_key_possessed,
672
                                                   current);
673
 
674
                if (!IS_ERR(skey_ref)) {
675
                        key_put(key);
676
                        key_ref = skey_ref;
677
                }
678
 
679
                break;
680
        }
681
 
682
        if (!partial) {
683
                ret = wait_for_key_construction(key, true);
684
                switch (ret) {
685
                case -ERESTARTSYS:
686
                        goto invalid_key;
687
                default:
688
                        if (perm)
689
                                goto invalid_key;
690
                case 0:
691
                        break;
692
                }
693
        } else if (perm) {
694
                ret = key_validate(key);
695
                if (ret < 0)
696
                        goto invalid_key;
697
        }
698
 
699
        ret = -EIO;
700
        if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
701
                goto invalid_key;
702
 
703
        /* check the permissions */
704
        ret = key_task_permission(key_ref, context, perm);
705
        if (ret < 0)
706
                goto invalid_key;
707
 
708
error:
709
        return key_ref;
710
 
711
invalid_key:
712
        key_ref_put(key_ref);
713
        key_ref = ERR_PTR(ret);
714
        goto error;
715
 
716
} /* end lookup_user_key() */
717
 
718
/*****************************************************************************/
719
/*
720
 * join the named keyring as the session keyring if possible, or attempt to
721
 * create a new one of that name if not
722
 * - if the name is NULL, an empty anonymous keyring is installed instead
723
 * - named session keyring joining is done with a semaphore held
724
 */
725
long join_session_keyring(const char *name)
726
{
727
        struct task_struct *tsk = current;
728
        struct key *keyring;
729
        long ret;
730
 
731
        /* if no name is provided, install an anonymous keyring */
732
        if (!name) {
733
                ret = install_session_keyring(tsk, NULL);
734
                if (ret < 0)
735
                        goto error;
736
 
737
                rcu_read_lock();
738
                ret = rcu_dereference(tsk->signal->session_keyring)->serial;
739
                rcu_read_unlock();
740
                goto error;
741
        }
742
 
743
        /* allow the user to join or create a named keyring */
744
        mutex_lock(&key_session_mutex);
745
 
746
        /* look for an existing keyring of this name */
747
        keyring = find_keyring_by_name(name, 0);
748
        if (PTR_ERR(keyring) == -ENOKEY) {
749
                /* not found - try and create a new one */
750
                keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk,
751
                                        KEY_ALLOC_IN_QUOTA, NULL);
752
                if (IS_ERR(keyring)) {
753
                        ret = PTR_ERR(keyring);
754
                        goto error2;
755
                }
756
        }
757
        else if (IS_ERR(keyring)) {
758
                ret = PTR_ERR(keyring);
759
                goto error2;
760
        }
761
 
762
        /* we've got a keyring - now to install it */
763
        ret = install_session_keyring(tsk, keyring);
764
        if (ret < 0)
765
                goto error2;
766
 
767
        ret = keyring->serial;
768
        key_put(keyring);
769
 
770
error2:
771
        mutex_unlock(&key_session_mutex);
772
error:
773
        return ret;
774
 
775
} /* end join_session_keyring() */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.