1
2
3
4
5
6
7
8
9
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 <keys/keyring-type.h>
20#include <linux/uaccess.h>
21#include "internal.h"
22
23#define rcu_dereference_locked_keyring(keyring) \
24 (rcu_dereference_protected( \
25 (keyring)->payload.subscriptions, \
26 rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
27
28#define rcu_deref_link_locked(klist, index, keyring) \
29 (rcu_dereference_protected( \
30 (klist)->keys[index], \
31 rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
32
33#define MAX_KEYRING_LINKS \
34 min_t(size_t, USHRT_MAX - 1, \
35 ((PAGE_SIZE - sizeof(struct keyring_list)) / sizeof(struct key *)))
36
37#define KEY_LINK_FIXQUOTA 1UL
38
39
40
41
42
43#define KEYRING_SEARCH_MAX_DEPTH 6
44
45
46
47
48#define KEYRING_NAME_HASH_SIZE (1 << 5)
49
50static struct list_head keyring_name_hash[KEYRING_NAME_HASH_SIZE];
51static DEFINE_RWLOCK(keyring_name_lock);
52
53static inline unsigned keyring_hash(const char *desc)
54{
55 unsigned bucket = 0;
56
57 for (; *desc; desc++)
58 bucket += (unsigned char)*desc;
59
60 return bucket & (KEYRING_NAME_HASH_SIZE - 1);
61}
62
63
64
65
66
67
68static int keyring_instantiate(struct key *keyring,
69 const void *data, size_t datalen);
70static int keyring_match(const struct key *keyring, const void *criterion);
71static void keyring_revoke(struct key *keyring);
72static void keyring_destroy(struct key *keyring);
73static void keyring_describe(const struct key *keyring, struct seq_file *m);
74static long keyring_read(const struct key *keyring,
75 char __user *buffer, size_t buflen);
76
77struct key_type key_type_keyring = {
78 .name = "keyring",
79 .def_datalen = sizeof(struct keyring_list),
80 .instantiate = keyring_instantiate,
81 .match = keyring_match,
82 .revoke = keyring_revoke,
83 .destroy = keyring_destroy,
84 .describe = keyring_describe,
85 .read = keyring_read,
86};
87EXPORT_SYMBOL(key_type_keyring);
88
89
90
91
92
93static DECLARE_RWSEM(keyring_serialise_link_sem);
94
95
96
97
98
99static void keyring_publish_name(struct key *keyring)
100{
101 int bucket;
102
103 if (keyring->description) {
104 bucket = keyring_hash(keyring->description);
105
106 write_lock(&keyring_name_lock);
107
108 if (!keyring_name_hash[bucket].next)
109 INIT_LIST_HEAD(&keyring_name_hash[bucket]);
110
111 list_add_tail(&keyring->type_data.link,
112 &keyring_name_hash[bucket]);
113
114 write_unlock(&keyring_name_lock);
115 }
116}
117
118
119
120
121
122
123static int keyring_instantiate(struct key *keyring,
124 const void *data, size_t datalen)
125{
126 int ret;
127
128 ret = -EINVAL;
129 if (datalen == 0) {
130
131 keyring_publish_name(keyring);
132 ret = 0;
133 }
134
135 return ret;
136}
137
138
139
140
141static int keyring_match(const struct key *keyring, const void *description)
142{
143 return keyring->description &&
144 strcmp(keyring->description, description) == 0;
145}
146
147
148
149
150
151
152
153
154
155
156static void keyring_destroy(struct key *keyring)
157{
158 struct keyring_list *klist;
159 int loop;
160
161 if (keyring->description) {
162 write_lock(&keyring_name_lock);
163
164 if (keyring->type_data.link.next != NULL &&
165 !list_empty(&keyring->type_data.link))
166 list_del(&keyring->type_data.link);
167
168 write_unlock(&keyring_name_lock);
169 }
170
171 klist = rcu_access_pointer(keyring->payload.subscriptions);
172 if (klist) {
173 for (loop = klist->nkeys - 1; loop >= 0; loop--)
174 key_put(rcu_access_pointer(klist->keys[loop]));
175 kfree(klist);
176 }
177}
178
179
180
181
182static void keyring_describe(const struct key *keyring, struct seq_file *m)
183{
184 struct keyring_list *klist;
185
186 if (keyring->description)
187 seq_puts(m, keyring->description);
188 else
189 seq_puts(m, "[anon]");
190
191 if (key_is_instantiated(keyring)) {
192 rcu_read_lock();
193 klist = rcu_dereference(keyring->payload.subscriptions);
194 if (klist)
195 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
196 else
197 seq_puts(m, ": empty");
198 rcu_read_unlock();
199 }
200}
201
202
203
204
205
206
207static long keyring_read(const struct key *keyring,
208 char __user *buffer, size_t buflen)
209{
210 struct keyring_list *klist;
211 struct key *key;
212 size_t qty, tmp;
213 int loop, ret;
214
215 ret = 0;
216 klist = rcu_dereference_locked_keyring(keyring);
217 if (klist) {
218
219 qty = klist->nkeys * sizeof(key_serial_t);
220
221 if (buffer && buflen > 0) {
222 if (buflen > qty)
223 buflen = qty;
224
225
226
227 ret = -EFAULT;
228
229 for (loop = 0; loop < klist->nkeys; loop++) {
230 key = rcu_deref_link_locked(klist, loop,
231 keyring);
232
233 tmp = sizeof(key_serial_t);
234 if (tmp > buflen)
235 tmp = buflen;
236
237 if (copy_to_user(buffer,
238 &key->serial,
239 tmp) != 0)
240 goto error;
241
242 buflen -= tmp;
243 if (buflen == 0)
244 break;
245 buffer += tmp;
246 }
247 }
248
249 ret = qty;
250 }
251
252error:
253 return ret;
254}
255
256
257
258
259struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
260 const struct cred *cred, unsigned long flags,
261 struct key *dest)
262{
263 struct key *keyring;
264 int ret;
265
266 keyring = key_alloc(&key_type_keyring, description,
267 uid, gid, cred,
268 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
269 flags);
270
271 if (!IS_ERR(keyring)) {
272 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
273 if (ret < 0) {
274 key_put(keyring);
275 keyring = ERR_PTR(ret);
276 }
277 }
278
279 return keyring;
280}
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318key_ref_t keyring_search_aux(key_ref_t keyring_ref,
319 const struct cred *cred,
320 struct key_type *type,
321 const void *description,
322 key_match_func_t match,
323 bool no_state_check)
324{
325 struct {
326
327 struct key *keyring;
328 struct keyring_list *keylist;
329 int kix;
330 } stack[KEYRING_SEARCH_MAX_DEPTH];
331
332 struct keyring_list *keylist;
333 struct timespec now;
334 unsigned long possessed, kflags;
335 struct key *keyring, *key;
336 key_ref_t key_ref;
337 long err;
338 int sp, nkeys, kix;
339
340 keyring = key_ref_to_ptr(keyring_ref);
341 possessed = is_key_possessed(keyring_ref);
342 key_check(keyring);
343
344
345 err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
346 if (err < 0) {
347 key_ref = ERR_PTR(err);
348 goto error;
349 }
350
351 key_ref = ERR_PTR(-ENOTDIR);
352 if (keyring->type != &key_type_keyring)
353 goto error;
354
355 rcu_read_lock();
356
357 now = current_kernel_time();
358 err = -EAGAIN;
359 sp = 0;
360
361
362
363 key_ref = ERR_PTR(-EAGAIN);
364 kflags = keyring->flags;
365 if (keyring->type == type && match(keyring, description)) {
366 key = keyring;
367 if (no_state_check)
368 goto found;
369
370
371
372 if (kflags & (1 << KEY_FLAG_REVOKED))
373 goto error_2;
374 if (key->expiry && now.tv_sec >= key->expiry)
375 goto error_2;
376 key_ref = ERR_PTR(key->type_data.reject_error);
377 if (kflags & (1 << KEY_FLAG_NEGATIVE))
378 goto error_2;
379 goto found;
380 }
381
382
383
384 key_ref = ERR_PTR(-EAGAIN);
385 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
386 (1 << KEY_FLAG_REVOKED) |
387 (1 << KEY_FLAG_NEGATIVE)) ||
388 (keyring->expiry && now.tv_sec >= keyring->expiry))
389 goto error_2;
390
391
392descend:
393 kflags = keyring->flags;
394 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
395 (1 << KEY_FLAG_REVOKED)))
396 goto not_this_keyring;
397
398 keylist = rcu_dereference(keyring->payload.subscriptions);
399 if (!keylist)
400 goto not_this_keyring;
401
402
403 nkeys = keylist->nkeys;
404 smp_rmb();
405 for (kix = 0; kix < nkeys; kix++) {
406 key = rcu_dereference(keylist->keys[kix]);
407 kflags = key->flags;
408
409
410 if (key->type != type)
411 continue;
412
413
414 if (!no_state_check) {
415 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
416 (1 << KEY_FLAG_REVOKED)))
417 continue;
418
419 if (key->expiry && now.tv_sec >= key->expiry)
420 continue;
421 }
422
423
424 if (!match(key, description))
425 continue;
426
427
428 if (key_task_permission(make_key_ref(key, possessed),
429 cred, KEY_SEARCH) < 0)
430 continue;
431
432 if (no_state_check)
433 goto found;
434
435
436 if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
437 err = key->type_data.reject_error;
438 continue;
439 }
440
441 goto found;
442 }
443
444
445 kix = 0;
446ascend:
447 nkeys = keylist->nkeys;
448 smp_rmb();
449 for (; kix < nkeys; kix++) {
450 key = rcu_dereference(keylist->keys[kix]);
451 if (key->type != &key_type_keyring)
452 continue;
453
454
455
456
457 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
458 continue;
459
460 if (key_task_permission(make_key_ref(key, possessed),
461 cred, KEY_SEARCH) < 0)
462 continue;
463
464
465 stack[sp].keyring = keyring;
466 stack[sp].keylist = keylist;
467 stack[sp].kix = kix;
468 sp++;
469
470
471 keyring = key;
472 goto descend;
473 }
474
475
476
477not_this_keyring:
478 if (sp > 0) {
479
480 sp--;
481 keyring = stack[sp].keyring;
482 keylist = stack[sp].keylist;
483 kix = stack[sp].kix + 1;
484 goto ascend;
485 }
486
487 key_ref = ERR_PTR(err);
488 goto error_2;
489
490
491found:
492 atomic_inc(&key->usage);
493 key->last_used_at = now.tv_sec;
494 keyring->last_used_at = now.tv_sec;
495 while (sp > 0)
496 stack[--sp].keyring->last_used_at = now.tv_sec;
497 key_check(key);
498 key_ref = make_key_ref(key, possessed);
499error_2:
500 rcu_read_unlock();
501error:
502 return key_ref;
503}
504
505
506
507
508
509
510
511
512
513
514key_ref_t keyring_search(key_ref_t keyring,
515 struct key_type *type,
516 const char *description)
517{
518 if (!type->match)
519 return ERR_PTR(-ENOKEY);
520
521 return keyring_search_aux(keyring, current->cred,
522 type, description, type->match, false);
523}
524EXPORT_SYMBOL(keyring_search);
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541key_ref_t __keyring_search_one(key_ref_t keyring_ref,
542 const struct key_type *ktype,
543 const char *description,
544 key_perm_t perm)
545{
546 struct keyring_list *klist;
547 unsigned long possessed;
548 struct key *keyring, *key;
549 int nkeys, loop;
550
551 keyring = key_ref_to_ptr(keyring_ref);
552 possessed = is_key_possessed(keyring_ref);
553
554 rcu_read_lock();
555
556 klist = rcu_dereference(keyring->payload.subscriptions);
557 if (klist) {
558 nkeys = klist->nkeys;
559 smp_rmb();
560 for (loop = 0; loop < nkeys ; loop++) {
561 key = rcu_dereference(klist->keys[loop]);
562 if (key->type == ktype &&
563 (!key->type->match ||
564 key->type->match(key, description)) &&
565 key_permission(make_key_ref(key, possessed),
566 perm) == 0 &&
567 !(key->flags & ((1 << KEY_FLAG_INVALIDATED) |
568 (1 << KEY_FLAG_REVOKED)))
569 )
570 goto found;
571 }
572 }
573
574 rcu_read_unlock();
575 return ERR_PTR(-ENOKEY);
576
577found:
578 atomic_inc(&key->usage);
579 keyring->last_used_at = key->last_used_at =
580 current_kernel_time().tv_sec;
581 rcu_read_unlock();
582 return make_key_ref(key, possessed);
583}
584
585
586
587
588
589
590
591
592
593
594
595
596struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
597{
598 struct key *keyring;
599 int bucket;
600
601 if (!name)
602 return ERR_PTR(-EINVAL);
603
604 bucket = keyring_hash(name);
605
606 read_lock(&keyring_name_lock);
607
608 if (keyring_name_hash[bucket].next) {
609
610
611 list_for_each_entry(keyring,
612 &keyring_name_hash[bucket],
613 type_data.link
614 ) {
615 if (keyring->user->user_ns != current_user_ns())
616 continue;
617
618 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
619 continue;
620
621 if (strcmp(keyring->description, name) != 0)
622 continue;
623
624 if (!skip_perm_check &&
625 key_permission(make_key_ref(keyring, 0),
626 KEY_SEARCH) < 0)
627 continue;
628
629
630
631
632 if (!atomic_inc_not_zero(&keyring->usage))
633 continue;
634 keyring->last_used_at = current_kernel_time().tv_sec;
635 goto out;
636 }
637 }
638
639 keyring = ERR_PTR(-ENOKEY);
640out:
641 read_unlock(&keyring_name_lock);
642 return keyring;
643}
644
645
646
647
648
649
650
651
652static int keyring_detect_cycle(struct key *A, struct key *B)
653{
654 struct {
655 struct keyring_list *keylist;
656 int kix;
657 } stack[KEYRING_SEARCH_MAX_DEPTH];
658
659 struct keyring_list *keylist;
660 struct key *subtree, *key;
661 int sp, nkeys, kix, ret;
662
663 rcu_read_lock();
664
665 ret = -EDEADLK;
666 if (A == B)
667 goto cycle_detected;
668
669 subtree = B;
670 sp = 0;
671
672
673descend:
674 if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
675 goto not_this_keyring;
676
677 keylist = rcu_dereference(subtree->payload.subscriptions);
678 if (!keylist)
679 goto not_this_keyring;
680 kix = 0;
681
682ascend:
683
684 nkeys = keylist->nkeys;
685 smp_rmb();
686 for (; kix < nkeys; kix++) {
687 key = rcu_dereference(keylist->keys[kix]);
688
689 if (key == A)
690 goto cycle_detected;
691
692
693 if (key->type == &key_type_keyring) {
694 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
695 goto too_deep;
696
697
698 stack[sp].keylist = keylist;
699 stack[sp].kix = kix;
700 sp++;
701
702
703 subtree = key;
704 goto descend;
705 }
706 }
707
708
709
710not_this_keyring:
711 if (sp > 0) {
712
713 sp--;
714 keylist = stack[sp].keylist;
715 kix = stack[sp].kix + 1;
716 goto ascend;
717 }
718
719 ret = 0;
720
721error:
722 rcu_read_unlock();
723 return ret;
724
725too_deep:
726 ret = -ELOOP;
727 goto error;
728
729cycle_detected:
730 ret = -EDEADLK;
731 goto error;
732}
733
734
735
736
737
738static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
739{
740 struct keyring_list *klist =
741 container_of(rcu, struct keyring_list, rcu);
742
743 if (klist->delkey != USHRT_MAX)
744 key_put(rcu_access_pointer(klist->keys[klist->delkey]));
745 kfree(klist);
746}
747
748
749
750
751int __key_link_begin(struct key *keyring, const struct key_type *type,
752 const char *description, unsigned long *_prealloc)
753 __acquires(&keyring->sem)
754{
755 struct keyring_list *klist, *nklist;
756 unsigned long prealloc;
757 unsigned max;
758 time_t lowest_lru;
759 size_t size;
760 int loop, lru, ret;
761
762 kenter("%d,%s,%s,", key_serial(keyring), type->name, description);
763
764 if (keyring->type != &key_type_keyring)
765 return -ENOTDIR;
766
767 down_write(&keyring->sem);
768
769 ret = -EKEYREVOKED;
770 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
771 goto error_krsem;
772
773
774
775 if (type == &key_type_keyring)
776 down_write(&keyring_serialise_link_sem);
777
778 klist = rcu_dereference_locked_keyring(keyring);
779
780
781 lru = -1;
782 if (klist && klist->nkeys > 0) {
783 lowest_lru = TIME_T_MAX;
784 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
785 struct key *key = rcu_deref_link_locked(klist, loop,
786 keyring);
787 if (key->type == type &&
788 strcmp(key->description, description) == 0) {
789
790
791
792
793 klist->delkey = loop;
794 prealloc = 0;
795 goto done;
796 }
797 if (key->last_used_at < lowest_lru) {
798 lowest_lru = key->last_used_at;
799 lru = loop;
800 }
801 }
802 }
803
804
805 if (klist &&
806 klist->nkeys == klist->maxkeys &&
807 klist->maxkeys >= MAX_KEYRING_LINKS) {
808 kdebug("LRU discard %d\n", lru);
809 klist->delkey = lru;
810 prealloc = 0;
811 goto done;
812 }
813
814
815 ret = key_payload_reserve(keyring,
816 keyring->datalen + KEYQUOTA_LINK_BYTES);
817 if (ret < 0)
818 goto error_sem;
819
820 if (klist && klist->nkeys < klist->maxkeys) {
821
822 klist->delkey = klist->nkeys;
823 prealloc = KEY_LINK_FIXQUOTA;
824 } else {
825
826 max = 4;
827 if (klist) {
828 max += klist->maxkeys;
829 if (max > MAX_KEYRING_LINKS)
830 max = MAX_KEYRING_LINKS;
831 BUG_ON(max <= klist->maxkeys);
832 }
833
834 size = sizeof(*klist) + sizeof(struct key *) * max;
835
836 ret = -ENOMEM;
837 nklist = kmalloc(size, GFP_KERNEL);
838 if (!nklist)
839 goto error_quota;
840
841 nklist->maxkeys = max;
842 if (klist) {
843 memcpy(nklist->keys, klist->keys,
844 sizeof(struct key *) * klist->nkeys);
845 nklist->delkey = klist->nkeys;
846 nklist->nkeys = klist->nkeys + 1;
847 klist->delkey = USHRT_MAX;
848 } else {
849 nklist->nkeys = 1;
850 nklist->delkey = 0;
851 }
852
853
854 RCU_INIT_POINTER(nklist->keys[nklist->delkey], NULL);
855 prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA;
856 }
857
858done:
859 *_prealloc = prealloc;
860 kleave(" = 0");
861 return 0;
862
863error_quota:
864
865 key_payload_reserve(keyring,
866 keyring->datalen - KEYQUOTA_LINK_BYTES);
867error_sem:
868 if (type == &key_type_keyring)
869 up_write(&keyring_serialise_link_sem);
870error_krsem:
871 up_write(&keyring->sem);
872 kleave(" = %d", ret);
873 return ret;
874}
875
876
877
878
879
880
881
882int __key_link_check_live_key(struct key *keyring, struct key *key)
883{
884 if (key->type == &key_type_keyring)
885
886
887 return keyring_detect_cycle(keyring, key);
888 return 0;
889}
890
891
892
893
894
895
896
897
898
899void __key_link(struct key *keyring, struct key *key,
900 unsigned long *_prealloc)
901{
902 struct keyring_list *klist, *nklist;
903 struct key *discard;
904
905 nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA);
906 *_prealloc = 0;
907
908 kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
909
910 klist = rcu_dereference_locked_keyring(keyring);
911
912 atomic_inc(&key->usage);
913 keyring->last_used_at = key->last_used_at =
914 current_kernel_time().tv_sec;
915
916
917
918 if (nklist) {
919 kdebug("reissue %hu/%hu/%hu",
920 nklist->delkey, nklist->nkeys, nklist->maxkeys);
921
922 RCU_INIT_POINTER(nklist->keys[nklist->delkey], key);
923
924 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
925
926
927
928 if (klist) {
929 kdebug("dispose %hu/%hu/%hu",
930 klist->delkey, klist->nkeys, klist->maxkeys);
931 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
932 }
933 } else if (klist->delkey < klist->nkeys) {
934 kdebug("replace %hu/%hu/%hu",
935 klist->delkey, klist->nkeys, klist->maxkeys);
936
937 discard = rcu_dereference_protected(
938 klist->keys[klist->delkey],
939 rwsem_is_locked(&keyring->sem));
940 rcu_assign_pointer(klist->keys[klist->delkey], key);
941
942
943 key_put(discard);
944 } else {
945
946 kdebug("append %hu/%hu/%hu",
947 klist->delkey, klist->nkeys, klist->maxkeys);
948
949 RCU_INIT_POINTER(klist->keys[klist->delkey], key);
950 smp_wmb();
951 klist->nkeys++;
952 }
953}
954
955
956
957
958
959
960void __key_link_end(struct key *keyring, struct key_type *type,
961 unsigned long prealloc)
962 __releases(&keyring->sem)
963{
964 BUG_ON(type == NULL);
965 BUG_ON(type->name == NULL);
966 kenter("%d,%s,%lx", keyring->serial, type->name, prealloc);
967
968 if (type == &key_type_keyring)
969 up_write(&keyring_serialise_link_sem);
970
971 if (prealloc) {
972 if (prealloc & KEY_LINK_FIXQUOTA)
973 key_payload_reserve(keyring,
974 keyring->datalen -
975 KEYQUOTA_LINK_BYTES);
976 kfree((struct keyring_list *)(prealloc & ~KEY_LINK_FIXQUOTA));
977 }
978 up_write(&keyring->sem);
979}
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001int key_link(struct key *keyring, struct key *key)
1002{
1003 unsigned long prealloc;
1004 int ret;
1005
1006 key_check(keyring);
1007 key_check(key);
1008
1009 ret = __key_link_begin(keyring, key->type, key->description, &prealloc);
1010 if (ret == 0) {
1011 ret = __key_link_check_live_key(keyring, key);
1012 if (ret == 0)
1013 __key_link(keyring, key, &prealloc);
1014 __key_link_end(keyring, key->type, prealloc);
1015 }
1016
1017 return ret;
1018}
1019EXPORT_SYMBOL(key_link);
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038int key_unlink(struct key *keyring, struct key *key)
1039{
1040 struct keyring_list *klist, *nklist;
1041 int loop, ret;
1042
1043 key_check(keyring);
1044 key_check(key);
1045
1046 ret = -ENOTDIR;
1047 if (keyring->type != &key_type_keyring)
1048 goto error;
1049
1050 down_write(&keyring->sem);
1051
1052 klist = rcu_dereference_locked_keyring(keyring);
1053 if (klist) {
1054
1055 for (loop = 0; loop < klist->nkeys; loop++)
1056 if (rcu_access_pointer(klist->keys[loop]) == key)
1057 goto key_is_present;
1058 }
1059
1060 up_write(&keyring->sem);
1061 ret = -ENOENT;
1062 goto error;
1063
1064key_is_present:
1065
1066 nklist = kmalloc(sizeof(*klist) +
1067 sizeof(struct key *) * klist->maxkeys,
1068 GFP_KERNEL);
1069 if (!nklist)
1070 goto nomem;
1071 nklist->maxkeys = klist->maxkeys;
1072 nklist->nkeys = klist->nkeys - 1;
1073
1074 if (loop > 0)
1075 memcpy(&nklist->keys[0],
1076 &klist->keys[0],
1077 loop * sizeof(struct key *));
1078
1079 if (loop < nklist->nkeys)
1080 memcpy(&nklist->keys[loop],
1081 &klist->keys[loop + 1],
1082 (nklist->nkeys - loop) * sizeof(struct key *));
1083
1084
1085 key_payload_reserve(keyring,
1086 keyring->datalen - KEYQUOTA_LINK_BYTES);
1087
1088 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
1089
1090 up_write(&keyring->sem);
1091
1092
1093 klist->delkey = loop;
1094 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
1095
1096 ret = 0;
1097
1098error:
1099 return ret;
1100nomem:
1101 ret = -ENOMEM;
1102 up_write(&keyring->sem);
1103 goto error;
1104}
1105EXPORT_SYMBOL(key_unlink);
1106
1107
1108
1109
1110
1111static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
1112{
1113 struct keyring_list *klist;
1114 int loop;
1115
1116 klist = container_of(rcu, struct keyring_list, rcu);
1117
1118 for (loop = klist->nkeys - 1; loop >= 0; loop--)
1119 key_put(rcu_access_pointer(klist->keys[loop]));
1120
1121 kfree(klist);
1122}
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132int keyring_clear(struct key *keyring)
1133{
1134 struct keyring_list *klist;
1135 int ret;
1136
1137 ret = -ENOTDIR;
1138 if (keyring->type == &key_type_keyring) {
1139
1140 down_write(&keyring->sem);
1141
1142 klist = rcu_dereference_locked_keyring(keyring);
1143 if (klist) {
1144
1145 key_payload_reserve(keyring,
1146 sizeof(struct keyring_list));
1147
1148 rcu_assign_pointer(keyring->payload.subscriptions,
1149 NULL);
1150 }
1151
1152 up_write(&keyring->sem);
1153
1154
1155 if (klist)
1156 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
1157
1158 ret = 0;
1159 }
1160
1161 return ret;
1162}
1163EXPORT_SYMBOL(keyring_clear);
1164
1165
1166
1167
1168
1169
1170static void keyring_revoke(struct key *keyring)
1171{
1172 struct keyring_list *klist;
1173
1174 klist = rcu_dereference_locked_keyring(keyring);
1175
1176
1177 key_payload_reserve(keyring, 0);
1178
1179 if (klist) {
1180 rcu_assign_pointer(keyring->payload.subscriptions, NULL);
1181 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
1182 }
1183}
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193void keyring_gc(struct key *keyring, time_t limit)
1194{
1195 struct keyring_list *klist, *new;
1196 struct key *key;
1197 int loop, keep, max;
1198
1199 kenter("{%x,%s}", key_serial(keyring), keyring->description);
1200
1201 down_write(&keyring->sem);
1202
1203 klist = rcu_dereference_locked_keyring(keyring);
1204 if (!klist)
1205 goto no_klist;
1206
1207
1208 keep = 0;
1209 for (loop = klist->nkeys - 1; loop >= 0; loop--)
1210 if (!key_is_dead(rcu_deref_link_locked(klist, loop, keyring),
1211 limit))
1212 keep++;
1213
1214 if (keep == klist->nkeys)
1215 goto just_return;
1216
1217
1218 max = roundup(keep, 4);
1219 new = kmalloc(sizeof(struct keyring_list) + max * sizeof(struct key *),
1220 GFP_KERNEL);
1221 if (!new)
1222 goto nomem;
1223 new->maxkeys = max;
1224 new->nkeys = 0;
1225 new->delkey = 0;
1226
1227
1228
1229
1230 keep = 0;
1231 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
1232 key = rcu_deref_link_locked(klist, loop, keyring);
1233 if (!key_is_dead(key, limit)) {
1234 if (keep >= max)
1235 goto discard_new;
1236 RCU_INIT_POINTER(new->keys[keep++], key_get(key));
1237 }
1238 }
1239 new->nkeys = keep;
1240
1241
1242 key_payload_reserve(keyring,
1243 sizeof(struct keyring_list) +
1244 KEYQUOTA_LINK_BYTES * keep);
1245
1246 if (keep == 0) {
1247 rcu_assign_pointer(keyring->payload.subscriptions, NULL);
1248 kfree(new);
1249 } else {
1250 rcu_assign_pointer(keyring->payload.subscriptions, new);
1251 }
1252
1253 up_write(&keyring->sem);
1254
1255 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
1256 kleave(" [yes]");
1257 return;
1258
1259discard_new:
1260 new->nkeys = keep;
1261 keyring_clear_rcu_disposal(&new->rcu);
1262 up_write(&keyring->sem);
1263 kleave(" [discard]");
1264 return;
1265
1266just_return:
1267 up_write(&keyring->sem);
1268 kleave(" [no dead]");
1269 return;
1270
1271no_klist:
1272 up_write(&keyring->sem);
1273 kleave(" [no_klist]");
1274 return;
1275
1276nomem:
1277 up_write(&keyring->sem);
1278 kleave(" [oom]");
1279}
1280