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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* keyring.c: keyring handling
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/security.h>
17
#include <linux/seq_file.h>
18
#include <linux/err.h>
19
#include <asm/uaccess.h>
20
#include "internal.h"
21
 
22
/*
23
 * when plumbing the depths of the key tree, this sets a hard limit set on how
24
 * deep we're willing to go
25
 */
26
#define KEYRING_SEARCH_MAX_DEPTH 6
27
 
28
/*
29
 * we keep all named keyrings in a hash to speed looking them up
30
 */
31
#define KEYRING_NAME_HASH_SIZE  (1 << 5)
32
 
33
static struct list_head keyring_name_hash[KEYRING_NAME_HASH_SIZE];
34
static DEFINE_RWLOCK(keyring_name_lock);
35
 
36
static inline unsigned keyring_hash(const char *desc)
37
{
38
        unsigned bucket = 0;
39
 
40
        for (; *desc; desc++)
41
                bucket += (unsigned char) *desc;
42
 
43
        return bucket & (KEYRING_NAME_HASH_SIZE - 1);
44
}
45
 
46
/*
47
 * the keyring type definition
48
 */
49
static int keyring_instantiate(struct key *keyring,
50
                               const void *data, size_t datalen);
51
static int keyring_match(const struct key *keyring, const void *criterion);
52
static void keyring_revoke(struct key *keyring);
53
static void keyring_destroy(struct key *keyring);
54
static void keyring_describe(const struct key *keyring, struct seq_file *m);
55
static long keyring_read(const struct key *keyring,
56
                         char __user *buffer, size_t buflen);
57
 
58
struct key_type key_type_keyring = {
59
        .name           = "keyring",
60
        .def_datalen    = sizeof(struct keyring_list),
61
        .instantiate    = keyring_instantiate,
62
        .match          = keyring_match,
63
        .revoke         = keyring_revoke,
64
        .destroy        = keyring_destroy,
65
        .describe       = keyring_describe,
66
        .read           = keyring_read,
67
};
68
 
69
EXPORT_SYMBOL(key_type_keyring);
70
 
71
/*
72
 * semaphore to serialise link/link calls to prevent two link calls in parallel
73
 * introducing a cycle
74
 */
75
static DECLARE_RWSEM(keyring_serialise_link_sem);
76
 
77
/*****************************************************************************/
78
/*
79
 * publish the name of a keyring so that it can be found by name (if it has
80
 * one)
81
 */
82
void keyring_publish_name(struct key *keyring)
83
{
84
        int bucket;
85
 
86
        if (keyring->description) {
87
                bucket = keyring_hash(keyring->description);
88
 
89
                write_lock(&keyring_name_lock);
90
 
91
                if (!keyring_name_hash[bucket].next)
92
                        INIT_LIST_HEAD(&keyring_name_hash[bucket]);
93
 
94
                list_add_tail(&keyring->type_data.link,
95
                              &keyring_name_hash[bucket]);
96
 
97
                write_unlock(&keyring_name_lock);
98
        }
99
 
100
} /* end keyring_publish_name() */
101
 
102
/*****************************************************************************/
103
/*
104
 * initialise a keyring
105
 * - we object if we were given any data
106
 */
107
static int keyring_instantiate(struct key *keyring,
108
                               const void *data, size_t datalen)
109
{
110
        int ret;
111
 
112
        ret = -EINVAL;
113
        if (datalen == 0) {
114
                /* make the keyring available by name if it has one */
115
                keyring_publish_name(keyring);
116
                ret = 0;
117
        }
118
 
119
        return ret;
120
 
121
} /* end keyring_instantiate() */
122
 
123
/*****************************************************************************/
124
/*
125
 * match keyrings on their name
126
 */
127
static int keyring_match(const struct key *keyring, const void *description)
128
{
129
        return keyring->description &&
130
                strcmp(keyring->description, description) == 0;
131
 
132
} /* end keyring_match() */
133
 
134
/*****************************************************************************/
135
/*
136
 * dispose of the data dangling from the corpse of a keyring
137
 */
138
static void keyring_destroy(struct key *keyring)
139
{
140
        struct keyring_list *klist;
141
        int loop;
142
 
143
        if (keyring->description) {
144
                write_lock(&keyring_name_lock);
145
 
146
                if (keyring->type_data.link.next != NULL &&
147
                    !list_empty(&keyring->type_data.link))
148
                        list_del(&keyring->type_data.link);
149
 
150
                write_unlock(&keyring_name_lock);
151
        }
152
 
153
        klist = rcu_dereference(keyring->payload.subscriptions);
154
        if (klist) {
155
                for (loop = klist->nkeys - 1; loop >= 0; loop--)
156
                        key_put(klist->keys[loop]);
157
                kfree(klist);
158
        }
159
 
160
} /* end keyring_destroy() */
161
 
162
/*****************************************************************************/
163
/*
164
 * describe the keyring
165
 */
166
static void keyring_describe(const struct key *keyring, struct seq_file *m)
167
{
168
        struct keyring_list *klist;
169
 
170
        if (keyring->description) {
171
                seq_puts(m, keyring->description);
172
        }
173
        else {
174
                seq_puts(m, "[anon]");
175
        }
176
 
177
        rcu_read_lock();
178
        klist = rcu_dereference(keyring->payload.subscriptions);
179
        if (klist)
180
                seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
181
        else
182
                seq_puts(m, ": empty");
183
        rcu_read_unlock();
184
 
185
} /* end keyring_describe() */
186
 
187
/*****************************************************************************/
188
/*
189
 * read a list of key IDs from the keyring's contents
190
 * - the keyring's semaphore is read-locked
191
 */
192
static long keyring_read(const struct key *keyring,
193
                         char __user *buffer, size_t buflen)
194
{
195
        struct keyring_list *klist;
196
        struct key *key;
197
        size_t qty, tmp;
198
        int loop, ret;
199
 
200
        ret = 0;
201
        klist = rcu_dereference(keyring->payload.subscriptions);
202
 
203
        if (klist) {
204
                /* calculate how much data we could return */
205
                qty = klist->nkeys * sizeof(key_serial_t);
206
 
207
                if (buffer && buflen > 0) {
208
                        if (buflen > qty)
209
                                buflen = qty;
210
 
211
                        /* copy the IDs of the subscribed keys into the
212
                         * buffer */
213
                        ret = -EFAULT;
214
 
215
                        for (loop = 0; loop < klist->nkeys; loop++) {
216
                                key = klist->keys[loop];
217
 
218
                                tmp = sizeof(key_serial_t);
219
                                if (tmp > buflen)
220
                                        tmp = buflen;
221
 
222
                                if (copy_to_user(buffer,
223
                                                 &key->serial,
224
                                                 tmp) != 0)
225
                                        goto error;
226
 
227
                                buflen -= tmp;
228
                                if (buflen == 0)
229
                                        break;
230
                                buffer += tmp;
231
                        }
232
                }
233
 
234
                ret = qty;
235
        }
236
 
237
 error:
238
        return ret;
239
 
240
} /* end keyring_read() */
241
 
242
/*****************************************************************************/
243
/*
244
 * allocate a keyring and link into the destination keyring
245
 */
246
struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
247
                          struct task_struct *ctx, unsigned long flags,
248
                          struct key *dest)
249
{
250
        struct key *keyring;
251
        int ret;
252
 
253
        keyring = key_alloc(&key_type_keyring, description,
254
                            uid, gid, ctx,
255
                            (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
256
                            flags);
257
 
258
        if (!IS_ERR(keyring)) {
259
                ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
260
                if (ret < 0) {
261
                        key_put(keyring);
262
                        keyring = ERR_PTR(ret);
263
                }
264
        }
265
 
266
        return keyring;
267
 
268
} /* end keyring_alloc() */
269
 
270
/*****************************************************************************/
271
/*
272
 * search the supplied keyring tree for a key that matches the criterion
273
 * - perform a breadth-then-depth search up to the prescribed limit
274
 * - we only find keys on which we have search permission
275
 * - we use the supplied match function to see if the description (or other
276
 *   feature of interest) matches
277
 * - we rely on RCU to prevent the keyring lists from disappearing on us
278
 * - we return -EAGAIN if we didn't find any matching key
279
 * - we return -ENOKEY if we only found negative matching keys
280
 * - we propagate the possession attribute from the keyring ref to the key ref
281
 */
282
key_ref_t keyring_search_aux(key_ref_t keyring_ref,
283
                             struct task_struct *context,
284
                             struct key_type *type,
285
                             const void *description,
286
                             key_match_func_t match)
287
{
288
        struct {
289
                struct keyring_list *keylist;
290
                int kix;
291
        } stack[KEYRING_SEARCH_MAX_DEPTH];
292
 
293
        struct keyring_list *keylist;
294
        struct timespec now;
295
        unsigned long possessed;
296
        struct key *keyring, *key;
297
        key_ref_t key_ref;
298
        long err;
299
        int sp, kix;
300
 
301
        keyring = key_ref_to_ptr(keyring_ref);
302
        possessed = is_key_possessed(keyring_ref);
303
        key_check(keyring);
304
 
305
        /* top keyring must have search permission to begin the search */
306
        err = key_task_permission(keyring_ref, context, KEY_SEARCH);
307
        if (err < 0) {
308
                key_ref = ERR_PTR(err);
309
                goto error;
310
        }
311
 
312
        key_ref = ERR_PTR(-ENOTDIR);
313
        if (keyring->type != &key_type_keyring)
314
                goto error;
315
 
316
        rcu_read_lock();
317
 
318
        now = current_kernel_time();
319
        err = -EAGAIN;
320
        sp = 0;
321
 
322
        /* start processing a new keyring */
323
descend:
324
        if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
325
                goto not_this_keyring;
326
 
327
        keylist = rcu_dereference(keyring->payload.subscriptions);
328
        if (!keylist)
329
                goto not_this_keyring;
330
 
331
        /* iterate through the keys in this keyring first */
332
        for (kix = 0; kix < keylist->nkeys; kix++) {
333
                key = keylist->keys[kix];
334
 
335
                /* ignore keys not of this type */
336
                if (key->type != type)
337
                        continue;
338
 
339
                /* skip revoked keys and expired keys */
340
                if (test_bit(KEY_FLAG_REVOKED, &key->flags))
341
                        continue;
342
 
343
                if (key->expiry && now.tv_sec >= key->expiry)
344
                        continue;
345
 
346
                /* keys that don't match */
347
                if (!match(key, description))
348
                        continue;
349
 
350
                /* key must have search permissions */
351
                if (key_task_permission(make_key_ref(key, possessed),
352
                                        context, KEY_SEARCH) < 0)
353
                        continue;
354
 
355
                /* we set a different error code if we find a negative key */
356
                if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
357
                        err = -ENOKEY;
358
                        continue;
359
                }
360
 
361
                goto found;
362
        }
363
 
364
        /* search through the keyrings nested in this one */
365
        kix = 0;
366
ascend:
367
        for (; kix < keylist->nkeys; kix++) {
368
                key = keylist->keys[kix];
369
                if (key->type != &key_type_keyring)
370
                        continue;
371
 
372
                /* recursively search nested keyrings
373
                 * - only search keyrings for which we have search permission
374
                 */
375
                if (sp >= KEYRING_SEARCH_MAX_DEPTH)
376
                        continue;
377
 
378
                if (key_task_permission(make_key_ref(key, possessed),
379
                                        context, KEY_SEARCH) < 0)
380
                        continue;
381
 
382
                /* stack the current position */
383
                stack[sp].keylist = keylist;
384
                stack[sp].kix = kix;
385
                sp++;
386
 
387
                /* begin again with the new keyring */
388
                keyring = key;
389
                goto descend;
390
        }
391
 
392
        /* the keyring we're looking at was disqualified or didn't contain a
393
         * matching key */
394
not_this_keyring:
395
        if (sp > 0) {
396
                /* resume the processing of a keyring higher up in the tree */
397
                sp--;
398
                keylist = stack[sp].keylist;
399
                kix = stack[sp].kix + 1;
400
                goto ascend;
401
        }
402
 
403
        key_ref = ERR_PTR(err);
404
        goto error_2;
405
 
406
        /* we found a viable match */
407
found:
408
        atomic_inc(&key->usage);
409
        key_check(key);
410
        key_ref = make_key_ref(key, possessed);
411
error_2:
412
        rcu_read_unlock();
413
error:
414
        return key_ref;
415
 
416
} /* end keyring_search_aux() */
417
 
418
/*****************************************************************************/
419
/*
420
 * search the supplied keyring tree for a key that matches the criterion
421
 * - perform a breadth-then-depth search up to the prescribed limit
422
 * - we only find keys on which we have search permission
423
 * - we readlock the keyrings as we search down the tree
424
 * - we return -EAGAIN if we didn't find any matching key
425
 * - we return -ENOKEY if we only found negative matching keys
426
 */
427
key_ref_t keyring_search(key_ref_t keyring,
428
                         struct key_type *type,
429
                         const char *description)
430
{
431
        if (!type->match)
432
                return ERR_PTR(-ENOKEY);
433
 
434
        return keyring_search_aux(keyring, current,
435
                                  type, description, type->match);
436
 
437
} /* end keyring_search() */
438
 
439
EXPORT_SYMBOL(keyring_search);
440
 
441
/*****************************************************************************/
442
/*
443
 * search the given keyring only (no recursion)
444
 * - keyring must be locked by caller
445
 * - caller must guarantee that the keyring is a keyring
446
 */
447
key_ref_t __keyring_search_one(key_ref_t keyring_ref,
448
                               const struct key_type *ktype,
449
                               const char *description,
450
                               key_perm_t perm)
451
{
452
        struct keyring_list *klist;
453
        unsigned long possessed;
454
        struct key *keyring, *key;
455
        int loop;
456
 
457
        keyring = key_ref_to_ptr(keyring_ref);
458
        possessed = is_key_possessed(keyring_ref);
459
 
460
        rcu_read_lock();
461
 
462
        klist = rcu_dereference(keyring->payload.subscriptions);
463
        if (klist) {
464
                for (loop = 0; loop < klist->nkeys; loop++) {
465
                        key = klist->keys[loop];
466
 
467
                        if (key->type == ktype &&
468
                            (!key->type->match ||
469
                             key->type->match(key, description)) &&
470
                            key_permission(make_key_ref(key, possessed),
471
                                           perm) == 0 &&
472
                            !test_bit(KEY_FLAG_REVOKED, &key->flags)
473
                            )
474
                                goto found;
475
                }
476
        }
477
 
478
        rcu_read_unlock();
479
        return ERR_PTR(-ENOKEY);
480
 
481
 found:
482
        atomic_inc(&key->usage);
483
        rcu_read_unlock();
484
        return make_key_ref(key, possessed);
485
 
486
} /* end __keyring_search_one() */
487
 
488
/*****************************************************************************/
489
/*
490
 * find a keyring with the specified name
491
 * - all named keyrings are searched
492
 * - only find keyrings with search permission for the process
493
 * - only find keyrings with a serial number greater than the one specified
494
 */
495
struct key *find_keyring_by_name(const char *name, key_serial_t bound)
496
{
497
        struct key *keyring;
498
        int bucket;
499
 
500
        keyring = ERR_PTR(-EINVAL);
501
        if (!name)
502
                goto error;
503
 
504
        bucket = keyring_hash(name);
505
 
506
        read_lock(&keyring_name_lock);
507
 
508
        if (keyring_name_hash[bucket].next) {
509
                /* search this hash bucket for a keyring with a matching name
510
                 * that's readable and that hasn't been revoked */
511
                list_for_each_entry(keyring,
512
                                    &keyring_name_hash[bucket],
513
                                    type_data.link
514
                                    ) {
515
                        if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
516
                                continue;
517
 
518
                        if (strcmp(keyring->description, name) != 0)
519
                                continue;
520
 
521
                        if (key_permission(make_key_ref(keyring, 0),
522
                                           KEY_SEARCH) < 0)
523
                                continue;
524
 
525
                        /* found a potential candidate, but we still need to
526
                         * check the serial number */
527
                        if (keyring->serial <= bound)
528
                                continue;
529
 
530
                        /* we've got a match */
531
                        atomic_inc(&keyring->usage);
532
                        read_unlock(&keyring_name_lock);
533
                        goto error;
534
                }
535
        }
536
 
537
        read_unlock(&keyring_name_lock);
538
        keyring = ERR_PTR(-ENOKEY);
539
 
540
 error:
541
        return keyring;
542
 
543
} /* end find_keyring_by_name() */
544
 
545
/*****************************************************************************/
546
/*
547
 * see if a cycle will will be created by inserting acyclic tree B in acyclic
548
 * tree A at the topmost level (ie: as a direct child of A)
549
 * - since we are adding B to A at the top level, checking for cycles should
550
 *   just be a matter of seeing if node A is somewhere in tree B
551
 */
552
static int keyring_detect_cycle(struct key *A, struct key *B)
553
{
554
        struct {
555
                struct keyring_list *keylist;
556
                int kix;
557
        } stack[KEYRING_SEARCH_MAX_DEPTH];
558
 
559
        struct keyring_list *keylist;
560
        struct key *subtree, *key;
561
        int sp, kix, ret;
562
 
563
        rcu_read_lock();
564
 
565
        ret = -EDEADLK;
566
        if (A == B)
567
                goto cycle_detected;
568
 
569
        subtree = B;
570
        sp = 0;
571
 
572
        /* start processing a new keyring */
573
 descend:
574
        if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
575
                goto not_this_keyring;
576
 
577
        keylist = rcu_dereference(subtree->payload.subscriptions);
578
        if (!keylist)
579
                goto not_this_keyring;
580
        kix = 0;
581
 
582
 ascend:
583
        /* iterate through the remaining keys in this keyring */
584
        for (; kix < keylist->nkeys; kix++) {
585
                key = keylist->keys[kix];
586
 
587
                if (key == A)
588
                        goto cycle_detected;
589
 
590
                /* recursively check nested keyrings */
591
                if (key->type == &key_type_keyring) {
592
                        if (sp >= KEYRING_SEARCH_MAX_DEPTH)
593
                                goto too_deep;
594
 
595
                        /* stack the current position */
596
                        stack[sp].keylist = keylist;
597
                        stack[sp].kix = kix;
598
                        sp++;
599
 
600
                        /* begin again with the new keyring */
601
                        subtree = key;
602
                        goto descend;
603
                }
604
        }
605
 
606
        /* the keyring we're looking at was disqualified or didn't contain a
607
         * matching key */
608
 not_this_keyring:
609
        if (sp > 0) {
610
                /* resume the checking of a keyring higher up in the tree */
611
                sp--;
612
                keylist = stack[sp].keylist;
613
                kix = stack[sp].kix + 1;
614
                goto ascend;
615
        }
616
 
617
        ret = 0; /* no cycles detected */
618
 
619
 error:
620
        rcu_read_unlock();
621
        return ret;
622
 
623
 too_deep:
624
        ret = -ELOOP;
625
        goto error;
626
 
627
 cycle_detected:
628
        ret = -EDEADLK;
629
        goto error;
630
 
631
} /* end keyring_detect_cycle() */
632
 
633
/*****************************************************************************/
634
/*
635
 * dispose of a keyring list after the RCU grace period
636
 */
637
static void keyring_link_rcu_disposal(struct rcu_head *rcu)
638
{
639
        struct keyring_list *klist =
640
                container_of(rcu, struct keyring_list, rcu);
641
 
642
        kfree(klist);
643
 
644
} /* end keyring_link_rcu_disposal() */
645
 
646
/*****************************************************************************/
647
/*
648
 * dispose of a keyring list after the RCU grace period, freeing the unlinked
649
 * key
650
 */
651
static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
652
{
653
        struct keyring_list *klist =
654
                container_of(rcu, struct keyring_list, rcu);
655
 
656
        key_put(klist->keys[klist->delkey]);
657
        kfree(klist);
658
 
659
} /* end keyring_unlink_rcu_disposal() */
660
 
661
/*****************************************************************************/
662
/*
663
 * link a key into to a keyring
664
 * - must be called with the keyring's semaphore write-locked
665
 * - discard already extant link to matching key if there is one
666
 */
667
int __key_link(struct key *keyring, struct key *key)
668
{
669
        struct keyring_list *klist, *nklist;
670
        unsigned max;
671
        size_t size;
672
        int loop, ret;
673
 
674
        ret = -EKEYREVOKED;
675
        if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
676
                goto error;
677
 
678
        ret = -ENOTDIR;
679
        if (keyring->type != &key_type_keyring)
680
                goto error;
681
 
682
        /* serialise link/link calls to prevent parallel calls causing a
683
         * cycle when applied to two keyring in opposite orders */
684
        down_write(&keyring_serialise_link_sem);
685
 
686
        /* check that we aren't going to create a cycle adding one keyring to
687
         * another */
688
        if (key->type == &key_type_keyring) {
689
                ret = keyring_detect_cycle(keyring, key);
690
                if (ret < 0)
691
                        goto error2;
692
        }
693
 
694
        /* see if there's a matching key we can displace */
695
        klist = keyring->payload.subscriptions;
696
 
697
        if (klist && klist->nkeys > 0) {
698
                struct key_type *type = key->type;
699
 
700
                for (loop = klist->nkeys - 1; loop >= 0; loop--) {
701
                        if (klist->keys[loop]->type == type &&
702
                            strcmp(klist->keys[loop]->description,
703
                                   key->description) == 0
704
                            ) {
705
                                /* found a match - replace with new key */
706
                                size = sizeof(struct key *) * klist->maxkeys;
707
                                size += sizeof(*klist);
708
                                BUG_ON(size > PAGE_SIZE);
709
 
710
                                ret = -ENOMEM;
711
                                nklist = kmemdup(klist, size, GFP_KERNEL);
712
                                if (!nklist)
713
                                        goto error2;
714
 
715
                                /* replace matched key */
716
                                atomic_inc(&key->usage);
717
                                nklist->keys[loop] = key;
718
 
719
                                rcu_assign_pointer(
720
                                        keyring->payload.subscriptions,
721
                                        nklist);
722
 
723
                                /* dispose of the old keyring list and the
724
                                 * displaced key */
725
                                klist->delkey = loop;
726
                                call_rcu(&klist->rcu,
727
                                         keyring_unlink_rcu_disposal);
728
 
729
                                goto done;
730
                        }
731
                }
732
        }
733
 
734
        /* check that we aren't going to overrun the user's quota */
735
        ret = key_payload_reserve(keyring,
736
                                  keyring->datalen + KEYQUOTA_LINK_BYTES);
737
        if (ret < 0)
738
                goto error2;
739
 
740
        klist = keyring->payload.subscriptions;
741
 
742
        if (klist && klist->nkeys < klist->maxkeys) {
743
                /* there's sufficient slack space to add directly */
744
                atomic_inc(&key->usage);
745
 
746
                klist->keys[klist->nkeys] = key;
747
                smp_wmb();
748
                klist->nkeys++;
749
                smp_wmb();
750
        }
751
        else {
752
                /* grow the key list */
753
                max = 4;
754
                if (klist)
755
                        max += klist->maxkeys;
756
 
757
                ret = -ENFILE;
758
                if (max > 65535)
759
                        goto error3;
760
                size = sizeof(*klist) + sizeof(struct key *) * max;
761
                if (size > PAGE_SIZE)
762
                        goto error3;
763
 
764
                ret = -ENOMEM;
765
                nklist = kmalloc(size, GFP_KERNEL);
766
                if (!nklist)
767
                        goto error3;
768
                nklist->maxkeys = max;
769
                nklist->nkeys = 0;
770
 
771
                if (klist) {
772
                        nklist->nkeys = klist->nkeys;
773
                        memcpy(nklist->keys,
774
                               klist->keys,
775
                               sizeof(struct key *) * klist->nkeys);
776
                }
777
 
778
                /* add the key into the new space */
779
                atomic_inc(&key->usage);
780
                nklist->keys[nklist->nkeys++] = key;
781
 
782
                rcu_assign_pointer(keyring->payload.subscriptions, nklist);
783
 
784
                /* dispose of the old keyring list */
785
                if (klist)
786
                        call_rcu(&klist->rcu, keyring_link_rcu_disposal);
787
        }
788
 
789
done:
790
        ret = 0;
791
error2:
792
        up_write(&keyring_serialise_link_sem);
793
error:
794
        return ret;
795
 
796
error3:
797
        /* undo the quota changes */
798
        key_payload_reserve(keyring,
799
                            keyring->datalen - KEYQUOTA_LINK_BYTES);
800
        goto error2;
801
 
802
} /* end __key_link() */
803
 
804
/*****************************************************************************/
805
/*
806
 * link a key to a keyring
807
 */
808
int key_link(struct key *keyring, struct key *key)
809
{
810
        int ret;
811
 
812
        key_check(keyring);
813
        key_check(key);
814
 
815
        down_write(&keyring->sem);
816
        ret = __key_link(keyring, key);
817
        up_write(&keyring->sem);
818
 
819
        return ret;
820
 
821
} /* end key_link() */
822
 
823
EXPORT_SYMBOL(key_link);
824
 
825
/*****************************************************************************/
826
/*
827
 * unlink the first link to a key from a keyring
828
 */
829
int key_unlink(struct key *keyring, struct key *key)
830
{
831
        struct keyring_list *klist, *nklist;
832
        int loop, ret;
833
 
834
        key_check(keyring);
835
        key_check(key);
836
 
837
        ret = -ENOTDIR;
838
        if (keyring->type != &key_type_keyring)
839
                goto error;
840
 
841
        down_write(&keyring->sem);
842
 
843
        klist = keyring->payload.subscriptions;
844
        if (klist) {
845
                /* search the keyring for the key */
846
                for (loop = 0; loop < klist->nkeys; loop++)
847
                        if (klist->keys[loop] == key)
848
                                goto key_is_present;
849
        }
850
 
851
        up_write(&keyring->sem);
852
        ret = -ENOENT;
853
        goto error;
854
 
855
key_is_present:
856
        /* we need to copy the key list for RCU purposes */
857
        nklist = kmalloc(sizeof(*klist) +
858
                         sizeof(struct key *) * klist->maxkeys,
859
                         GFP_KERNEL);
860
        if (!nklist)
861
                goto nomem;
862
        nklist->maxkeys = klist->maxkeys;
863
        nklist->nkeys = klist->nkeys - 1;
864
 
865
        if (loop > 0)
866
                memcpy(&nklist->keys[0],
867
                       &klist->keys[0],
868
                       loop * sizeof(struct key *));
869
 
870
        if (loop < nklist->nkeys)
871
                memcpy(&nklist->keys[loop],
872
                       &klist->keys[loop + 1],
873
                       (nklist->nkeys - loop) * sizeof(struct key *));
874
 
875
        /* adjust the user's quota */
876
        key_payload_reserve(keyring,
877
                            keyring->datalen - KEYQUOTA_LINK_BYTES);
878
 
879
        rcu_assign_pointer(keyring->payload.subscriptions, nklist);
880
 
881
        up_write(&keyring->sem);
882
 
883
        /* schedule for later cleanup */
884
        klist->delkey = loop;
885
        call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
886
 
887
        ret = 0;
888
 
889
error:
890
        return ret;
891
nomem:
892
        ret = -ENOMEM;
893
        up_write(&keyring->sem);
894
        goto error;
895
 
896
} /* end key_unlink() */
897
 
898
EXPORT_SYMBOL(key_unlink);
899
 
900
/*****************************************************************************/
901
/*
902
 * dispose of a keyring list after the RCU grace period, releasing the keys it
903
 * links to
904
 */
905
static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
906
{
907
        struct keyring_list *klist;
908
        int loop;
909
 
910
        klist = container_of(rcu, struct keyring_list, rcu);
911
 
912
        for (loop = klist->nkeys - 1; loop >= 0; loop--)
913
                key_put(klist->keys[loop]);
914
 
915
        kfree(klist);
916
 
917
} /* end keyring_clear_rcu_disposal() */
918
 
919
/*****************************************************************************/
920
/*
921
 * clear the specified process keyring
922
 * - implements keyctl(KEYCTL_CLEAR)
923
 */
924
int keyring_clear(struct key *keyring)
925
{
926
        struct keyring_list *klist;
927
        int ret;
928
 
929
        ret = -ENOTDIR;
930
        if (keyring->type == &key_type_keyring) {
931
                /* detach the pointer block with the locks held */
932
                down_write(&keyring->sem);
933
 
934
                klist = keyring->payload.subscriptions;
935
                if (klist) {
936
                        /* adjust the quota */
937
                        key_payload_reserve(keyring,
938
                                            sizeof(struct keyring_list));
939
 
940
                        rcu_assign_pointer(keyring->payload.subscriptions,
941
                                           NULL);
942
                }
943
 
944
                up_write(&keyring->sem);
945
 
946
                /* free the keys after the locks have been dropped */
947
                if (klist)
948
                        call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
949
 
950
                ret = 0;
951
        }
952
 
953
        return ret;
954
 
955
} /* end keyring_clear() */
956
 
957
EXPORT_SYMBOL(keyring_clear);
958
 
959
/*****************************************************************************/
960
/*
961
 * dispose of the links from a revoked keyring
962
 * - called with the key sem write-locked
963
 */
964
static void keyring_revoke(struct key *keyring)
965
{
966
        struct keyring_list *klist = keyring->payload.subscriptions;
967
 
968
        /* adjust the quota */
969
        key_payload_reserve(keyring, 0);
970
 
971
        if (klist) {
972
                rcu_assign_pointer(keyring->payload.subscriptions, NULL);
973
                call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
974
        }
975
 
976
} /* end keyring_revoke() */

powered by: WebSVN 2.1.0

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