aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /security/keys/keyring.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c214
1 files changed, 80 insertions, 134 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 6ece7f2e570..30e242f7bd0 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -25,15 +25,6 @@
25 (keyring)->payload.subscriptions, \ 25 (keyring)->payload.subscriptions, \
26 rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem))) 26 rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
27 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 28#define KEY_LINK_FIXQUOTA 1UL
38 29
39/* 30/*
@@ -66,7 +57,7 @@ static inline unsigned keyring_hash(const char *desc)
66 * operations. 57 * operations.
67 */ 58 */
68static int keyring_instantiate(struct key *keyring, 59static int keyring_instantiate(struct key *keyring,
69 struct key_preparsed_payload *prep); 60 const void *data, size_t datalen);
70static int keyring_match(const struct key *keyring, const void *criterion); 61static int keyring_match(const struct key *keyring, const void *criterion);
71static void keyring_revoke(struct key *keyring); 62static void keyring_revoke(struct key *keyring);
72static void keyring_destroy(struct key *keyring); 63static void keyring_destroy(struct key *keyring);
@@ -121,12 +112,12 @@ static void keyring_publish_name(struct key *keyring)
121 * Returns 0 on success, -EINVAL if given any data. 112 * Returns 0 on success, -EINVAL if given any data.
122 */ 113 */
123static int keyring_instantiate(struct key *keyring, 114static int keyring_instantiate(struct key *keyring,
124 struct key_preparsed_payload *prep) 115 const void *data, size_t datalen)
125{ 116{
126 int ret; 117 int ret;
127 118
128 ret = -EINVAL; 119 ret = -EINVAL;
129 if (prep->datalen == 0) { 120 if (datalen == 0) {
130 /* make the keyring available by name if it has one */ 121 /* make the keyring available by name if it has one */
131 keyring_publish_name(keyring); 122 keyring_publish_name(keyring);
132 ret = 0; 123 ret = 0;
@@ -147,11 +138,6 @@ static int keyring_match(const struct key *keyring, const void *description)
147/* 138/*
148 * Clean up a keyring when it is destroyed. Unpublish its name if it had one 139 * Clean up a keyring when it is destroyed. Unpublish its name if it had one
149 * and dispose of its data. 140 * and dispose of its data.
150 *
151 * The garbage collector detects the final key_put(), removes the keyring from
152 * the serial number tree and then does RCU synchronisation before coming here,
153 * so we shouldn't need to worry about code poking around here with the RCU
154 * readlock held by this time.
155 */ 141 */
156static void keyring_destroy(struct key *keyring) 142static void keyring_destroy(struct key *keyring)
157{ 143{
@@ -168,10 +154,11 @@ static void keyring_destroy(struct key *keyring)
168 write_unlock(&keyring_name_lock); 154 write_unlock(&keyring_name_lock);
169 } 155 }
170 156
171 klist = rcu_access_pointer(keyring->payload.subscriptions); 157 klist = rcu_dereference_check(keyring->payload.subscriptions,
158 atomic_read(&keyring->usage) == 0);
172 if (klist) { 159 if (klist) {
173 for (loop = klist->nkeys - 1; loop >= 0; loop--) 160 for (loop = klist->nkeys - 1; loop >= 0; loop--)
174 key_put(rcu_access_pointer(klist->keys[loop])); 161 key_put(klist->keys[loop]);
175 kfree(klist); 162 kfree(klist);
176 } 163 }
177} 164}
@@ -227,8 +214,7 @@ static long keyring_read(const struct key *keyring,
227 ret = -EFAULT; 214 ret = -EFAULT;
228 215
229 for (loop = 0; loop < klist->nkeys; loop++) { 216 for (loop = 0; loop < klist->nkeys; loop++) {
230 key = rcu_deref_link_locked(klist, loop, 217 key = klist->keys[loop];
231 keyring);
232 218
233 tmp = sizeof(key_serial_t); 219 tmp = sizeof(key_serial_t);
234 if (tmp > buflen) 220 if (tmp > buflen)
@@ -256,15 +242,18 @@ error:
256/* 242/*
257 * Allocate a keyring and link into the destination keyring. 243 * Allocate a keyring and link into the destination keyring.
258 */ 244 */
259struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 245struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
260 const struct cred *cred, key_perm_t perm, 246 const struct cred *cred, unsigned long flags,
261 unsigned long flags, struct key *dest) 247 struct key *dest)
262{ 248{
263 struct key *keyring; 249 struct key *keyring;
264 int ret; 250 int ret;
265 251
266 keyring = key_alloc(&key_type_keyring, description, 252 keyring = key_alloc(&key_type_keyring, description,
267 uid, gid, cred, perm, flags); 253 uid, gid, cred,
254 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
255 flags);
256
268 if (!IS_ERR(keyring)) { 257 if (!IS_ERR(keyring)) {
269 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 258 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
270 if (ret < 0) { 259 if (ret < 0) {
@@ -275,7 +264,6 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
275 264
276 return keyring; 265 return keyring;
277} 266}
278EXPORT_SYMBOL(keyring_alloc);
279 267
280/** 268/**
281 * keyring_search_aux - Search a keyring tree for a key matching some criteria 269 * keyring_search_aux - Search a keyring tree for a key matching some criteria
@@ -321,8 +309,6 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
321 bool no_state_check) 309 bool no_state_check)
322{ 310{
323 struct { 311 struct {
324 /* Need a separate keylist pointer for RCU purposes */
325 struct key *keyring;
326 struct keyring_list *keylist; 312 struct keyring_list *keylist;
327 int kix; 313 int kix;
328 } stack[KEYRING_SEARCH_MAX_DEPTH]; 314 } stack[KEYRING_SEARCH_MAX_DEPTH];
@@ -333,7 +319,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
333 struct key *keyring, *key; 319 struct key *keyring, *key;
334 key_ref_t key_ref; 320 key_ref_t key_ref;
335 long err; 321 long err;
336 int sp, nkeys, kix; 322 int sp, kix;
337 323
338 keyring = key_ref_to_ptr(keyring_ref); 324 keyring = key_ref_to_ptr(keyring_ref);
339 possessed = is_key_possessed(keyring_ref); 325 possessed = is_key_possessed(keyring_ref);
@@ -380,17 +366,13 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
380 /* otherwise, the top keyring must not be revoked, expired, or 366 /* otherwise, the top keyring must not be revoked, expired, or
381 * negatively instantiated if we are to search it */ 367 * negatively instantiated if we are to search it */
382 key_ref = ERR_PTR(-EAGAIN); 368 key_ref = ERR_PTR(-EAGAIN);
383 if (kflags & ((1 << KEY_FLAG_INVALIDATED) | 369 if (kflags & ((1 << KEY_FLAG_REVOKED) | (1 << KEY_FLAG_NEGATIVE)) ||
384 (1 << KEY_FLAG_REVOKED) |
385 (1 << KEY_FLAG_NEGATIVE)) ||
386 (keyring->expiry && now.tv_sec >= keyring->expiry)) 370 (keyring->expiry && now.tv_sec >= keyring->expiry))
387 goto error_2; 371 goto error_2;
388 372
389 /* start processing a new keyring */ 373 /* start processing a new keyring */
390descend: 374descend:
391 kflags = keyring->flags; 375 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
392 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
393 (1 << KEY_FLAG_REVOKED)))
394 goto not_this_keyring; 376 goto not_this_keyring;
395 377
396 keylist = rcu_dereference(keyring->payload.subscriptions); 378 keylist = rcu_dereference(keyring->payload.subscriptions);
@@ -398,20 +380,17 @@ descend:
398 goto not_this_keyring; 380 goto not_this_keyring;
399 381
400 /* iterate through the keys in this keyring first */ 382 /* iterate through the keys in this keyring first */
401 nkeys = keylist->nkeys; 383 for (kix = 0; kix < keylist->nkeys; kix++) {
402 smp_rmb(); 384 key = keylist->keys[kix];
403 for (kix = 0; kix < nkeys; kix++) {
404 key = rcu_dereference(keylist->keys[kix]);
405 kflags = key->flags; 385 kflags = key->flags;
406 386
407 /* ignore keys not of this type */ 387 /* ignore keys not of this type */
408 if (key->type != type) 388 if (key->type != type)
409 continue; 389 continue;
410 390
411 /* skip invalidated, revoked and expired keys */ 391 /* skip revoked keys and expired keys */
412 if (!no_state_check) { 392 if (!no_state_check) {
413 if (kflags & ((1 << KEY_FLAG_INVALIDATED) | 393 if (kflags & (1 << KEY_FLAG_REVOKED))
414 (1 << KEY_FLAG_REVOKED)))
415 continue; 394 continue;
416 395
417 if (key->expiry && now.tv_sec >= key->expiry) 396 if (key->expiry && now.tv_sec >= key->expiry)
@@ -442,10 +421,8 @@ descend:
442 /* search through the keyrings nested in this one */ 421 /* search through the keyrings nested in this one */
443 kix = 0; 422 kix = 0;
444ascend: 423ascend:
445 nkeys = keylist->nkeys; 424 for (; kix < keylist->nkeys; kix++) {
446 smp_rmb(); 425 key = keylist->keys[kix];
447 for (; kix < nkeys; kix++) {
448 key = rcu_dereference(keylist->keys[kix]);
449 if (key->type != &key_type_keyring) 426 if (key->type != &key_type_keyring)
450 continue; 427 continue;
451 428
@@ -460,7 +437,6 @@ ascend:
460 continue; 437 continue;
461 438
462 /* stack the current position */ 439 /* stack the current position */
463 stack[sp].keyring = keyring;
464 stack[sp].keylist = keylist; 440 stack[sp].keylist = keylist;
465 stack[sp].kix = kix; 441 stack[sp].kix = kix;
466 sp++; 442 sp++;
@@ -476,7 +452,6 @@ not_this_keyring:
476 if (sp > 0) { 452 if (sp > 0) {
477 /* resume the processing of a keyring higher up in the tree */ 453 /* resume the processing of a keyring higher up in the tree */
478 sp--; 454 sp--;
479 keyring = stack[sp].keyring;
480 keylist = stack[sp].keylist; 455 keylist = stack[sp].keylist;
481 kix = stack[sp].kix + 1; 456 kix = stack[sp].kix + 1;
482 goto ascend; 457 goto ascend;
@@ -488,10 +463,6 @@ not_this_keyring:
488 /* we found a viable match */ 463 /* we found a viable match */
489found: 464found:
490 atomic_inc(&key->usage); 465 atomic_inc(&key->usage);
491 key->last_used_at = now.tv_sec;
492 keyring->last_used_at = now.tv_sec;
493 while (sp > 0)
494 stack[--sp].keyring->last_used_at = now.tv_sec;
495 key_check(key); 466 key_check(key);
496 key_ref = make_key_ref(key, possessed); 467 key_ref = make_key_ref(key, possessed);
497error_2: 468error_2:
@@ -544,7 +515,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
544 struct keyring_list *klist; 515 struct keyring_list *klist;
545 unsigned long possessed; 516 unsigned long possessed;
546 struct key *keyring, *key; 517 struct key *keyring, *key;
547 int nkeys, loop; 518 int loop;
548 519
549 keyring = key_ref_to_ptr(keyring_ref); 520 keyring = key_ref_to_ptr(keyring_ref);
550 possessed = is_key_possessed(keyring_ref); 521 possessed = is_key_possessed(keyring_ref);
@@ -553,17 +524,15 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
553 524
554 klist = rcu_dereference(keyring->payload.subscriptions); 525 klist = rcu_dereference(keyring->payload.subscriptions);
555 if (klist) { 526 if (klist) {
556 nkeys = klist->nkeys; 527 for (loop = 0; loop < klist->nkeys; loop++) {
557 smp_rmb(); 528 key = klist->keys[loop];
558 for (loop = 0; loop < nkeys ; loop++) { 529
559 key = rcu_dereference(klist->keys[loop]);
560 if (key->type == ktype && 530 if (key->type == ktype &&
561 (!key->type->match || 531 (!key->type->match ||
562 key->type->match(key, description)) && 532 key->type->match(key, description)) &&
563 key_permission(make_key_ref(key, possessed), 533 key_permission(make_key_ref(key, possessed),
564 perm) == 0 && 534 perm) == 0 &&
565 !(key->flags & ((1 << KEY_FLAG_INVALIDATED) | 535 !test_bit(KEY_FLAG_REVOKED, &key->flags)
566 (1 << KEY_FLAG_REVOKED)))
567 ) 536 )
568 goto found; 537 goto found;
569 } 538 }
@@ -574,8 +543,6 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
574 543
575found: 544found:
576 atomic_inc(&key->usage); 545 atomic_inc(&key->usage);
577 keyring->last_used_at = key->last_used_at =
578 current_kernel_time().tv_sec;
579 rcu_read_unlock(); 546 rcu_read_unlock();
580 return make_key_ref(key, possessed); 547 return make_key_ref(key, possessed);
581} 548}
@@ -610,7 +577,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
610 &keyring_name_hash[bucket], 577 &keyring_name_hash[bucket],
611 type_data.link 578 type_data.link
612 ) { 579 ) {
613 if (!kuid_has_mapping(current_user_ns(), keyring->user->uid)) 580 if (keyring->user->user_ns != current_user_ns())
614 continue; 581 continue;
615 582
616 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 583 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
@@ -629,7 +596,6 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
629 * (ie. it has a zero usage count) */ 596 * (ie. it has a zero usage count) */
630 if (!atomic_inc_not_zero(&keyring->usage)) 597 if (!atomic_inc_not_zero(&keyring->usage))
631 continue; 598 continue;
632 keyring->last_used_at = current_kernel_time().tv_sec;
633 goto out; 599 goto out;
634 } 600 }
635 } 601 }
@@ -656,7 +622,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
656 622
657 struct keyring_list *keylist; 623 struct keyring_list *keylist;
658 struct key *subtree, *key; 624 struct key *subtree, *key;
659 int sp, nkeys, kix, ret; 625 int sp, kix, ret;
660 626
661 rcu_read_lock(); 627 rcu_read_lock();
662 628
@@ -679,10 +645,8 @@ descend:
679 645
680ascend: 646ascend:
681 /* iterate through the remaining keys in this keyring */ 647 /* iterate through the remaining keys in this keyring */
682 nkeys = keylist->nkeys; 648 for (; kix < keylist->nkeys; kix++) {
683 smp_rmb(); 649 key = keylist->keys[kix];
684 for (; kix < nkeys; kix++) {
685 key = rcu_dereference(keylist->keys[kix]);
686 650
687 if (key == A) 651 if (key == A)
688 goto cycle_detected; 652 goto cycle_detected;
@@ -739,7 +703,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
739 container_of(rcu, struct keyring_list, rcu); 703 container_of(rcu, struct keyring_list, rcu);
740 704
741 if (klist->delkey != USHRT_MAX) 705 if (klist->delkey != USHRT_MAX)
742 key_put(rcu_access_pointer(klist->keys[klist->delkey])); 706 key_put(klist->keys[klist->delkey]);
743 kfree(klist); 707 kfree(klist);
744} 708}
745 709
@@ -749,14 +713,12 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
749int __key_link_begin(struct key *keyring, const struct key_type *type, 713int __key_link_begin(struct key *keyring, const struct key_type *type,
750 const char *description, unsigned long *_prealloc) 714 const char *description, unsigned long *_prealloc)
751 __acquires(&keyring->sem) 715 __acquires(&keyring->sem)
752 __acquires(&keyring_serialise_link_sem)
753{ 716{
754 struct keyring_list *klist, *nklist; 717 struct keyring_list *klist, *nklist;
755 unsigned long prealloc; 718 unsigned long prealloc;
756 unsigned max; 719 unsigned max;
757 time_t lowest_lru;
758 size_t size; 720 size_t size;
759 int loop, lru, ret; 721 int loop, ret;
760 722
761 kenter("%d,%s,%s,", key_serial(keyring), type->name, description); 723 kenter("%d,%s,%s,", key_serial(keyring), type->name, description);
762 724
@@ -777,39 +739,31 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
777 klist = rcu_dereference_locked_keyring(keyring); 739 klist = rcu_dereference_locked_keyring(keyring);
778 740
779 /* see if there's a matching key we can displace */ 741 /* see if there's a matching key we can displace */
780 lru = -1;
781 if (klist && klist->nkeys > 0) { 742 if (klist && klist->nkeys > 0) {
782 lowest_lru = TIME_T_MAX;
783 for (loop = klist->nkeys - 1; loop >= 0; loop--) { 743 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
784 struct key *key = rcu_deref_link_locked(klist, loop, 744 if (klist->keys[loop]->type == type &&
785 keyring); 745 strcmp(klist->keys[loop]->description,
786 if (key->type == type && 746 description) == 0
787 strcmp(key->description, description) == 0) { 747 ) {
788 /* Found a match - we'll replace the link with 748 /* found a match - we'll replace this one with
789 * one to the new key. We record the slot 749 * the new key */
790 * position. 750 size = sizeof(struct key *) * klist->maxkeys;
791 */ 751 size += sizeof(*klist);
792 klist->delkey = loop; 752 BUG_ON(size > PAGE_SIZE);
793 prealloc = 0; 753
754 ret = -ENOMEM;
755 nklist = kmemdup(klist, size, GFP_KERNEL);
756 if (!nklist)
757 goto error_sem;
758
759 /* note replacement slot */
760 klist->delkey = nklist->delkey = loop;
761 prealloc = (unsigned long)nklist;
794 goto done; 762 goto done;
795 } 763 }
796 if (key->last_used_at < lowest_lru) {
797 lowest_lru = key->last_used_at;
798 lru = loop;
799 }
800 } 764 }
801 } 765 }
802 766
803 /* If the keyring is full then do an LRU discard */
804 if (klist &&
805 klist->nkeys == klist->maxkeys &&
806 klist->maxkeys >= MAX_KEYRING_LINKS) {
807 kdebug("LRU discard %d\n", lru);
808 klist->delkey = lru;
809 prealloc = 0;
810 goto done;
811 }
812
813 /* check that we aren't going to overrun the user's quota */ 767 /* check that we aren't going to overrun the user's quota */
814 ret = key_payload_reserve(keyring, 768 ret = key_payload_reserve(keyring,
815 keyring->datalen + KEYQUOTA_LINK_BYTES); 769 keyring->datalen + KEYQUOTA_LINK_BYTES);
@@ -818,19 +772,20 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
818 772
819 if (klist && klist->nkeys < klist->maxkeys) { 773 if (klist && klist->nkeys < klist->maxkeys) {
820 /* there's sufficient slack space to append directly */ 774 /* there's sufficient slack space to append directly */
821 klist->delkey = klist->nkeys; 775 nklist = NULL;
822 prealloc = KEY_LINK_FIXQUOTA; 776 prealloc = KEY_LINK_FIXQUOTA;
823 } else { 777 } else {
824 /* grow the key list */ 778 /* grow the key list */
825 max = 4; 779 max = 4;
826 if (klist) { 780 if (klist)
827 max += klist->maxkeys; 781 max += klist->maxkeys;
828 if (max > MAX_KEYRING_LINKS)
829 max = MAX_KEYRING_LINKS;
830 BUG_ON(max <= klist->maxkeys);
831 }
832 782
783 ret = -ENFILE;
784 if (max > USHRT_MAX - 1)
785 goto error_quota;
833 size = sizeof(*klist) + sizeof(struct key *) * max; 786 size = sizeof(*klist) + sizeof(struct key *) * max;
787 if (size > PAGE_SIZE)
788 goto error_quota;
834 789
835 ret = -ENOMEM; 790 ret = -ENOMEM;
836 nklist = kmalloc(size, GFP_KERNEL); 791 nklist = kmalloc(size, GFP_KERNEL);
@@ -850,10 +805,10 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
850 } 805 }
851 806
852 /* add the key into the new space */ 807 /* add the key into the new space */
853 RCU_INIT_POINTER(nklist->keys[nklist->delkey], NULL); 808 nklist->keys[nklist->delkey] = NULL;
854 prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA;
855 } 809 }
856 810
811 prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA;
857done: 812done:
858 *_prealloc = prealloc; 813 *_prealloc = prealloc;
859 kleave(" = 0"); 814 kleave(" = 0");
@@ -899,26 +854,24 @@ void __key_link(struct key *keyring, struct key *key,
899 unsigned long *_prealloc) 854 unsigned long *_prealloc)
900{ 855{
901 struct keyring_list *klist, *nklist; 856 struct keyring_list *klist, *nklist;
902 struct key *discard;
903 857
904 nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA); 858 nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA);
905 *_prealloc = 0; 859 *_prealloc = 0;
906 860
907 kenter("%d,%d,%p", keyring->serial, key->serial, nklist); 861 kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
908 862
909 klist = rcu_dereference_locked_keyring(keyring); 863 klist = rcu_dereference_protected(keyring->payload.subscriptions,
864 rwsem_is_locked(&keyring->sem));
910 865
911 atomic_inc(&key->usage); 866 atomic_inc(&key->usage);
912 keyring->last_used_at = key->last_used_at =
913 current_kernel_time().tv_sec;
914 867
915 /* there's a matching key we can displace or an empty slot in a newly 868 /* there's a matching key we can displace or an empty slot in a newly
916 * allocated list we can fill */ 869 * allocated list we can fill */
917 if (nklist) { 870 if (nklist) {
918 kdebug("reissue %hu/%hu/%hu", 871 kdebug("replace %hu/%hu/%hu",
919 nklist->delkey, nklist->nkeys, nklist->maxkeys); 872 nklist->delkey, nklist->nkeys, nklist->maxkeys);
920 873
921 RCU_INIT_POINTER(nklist->keys[nklist->delkey], key); 874 nklist->keys[nklist->delkey] = key;
922 875
923 rcu_assign_pointer(keyring->payload.subscriptions, nklist); 876 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
924 877
@@ -929,23 +882,9 @@ void __key_link(struct key *keyring, struct key *key,
929 klist->delkey, klist->nkeys, klist->maxkeys); 882 klist->delkey, klist->nkeys, klist->maxkeys);
930 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal); 883 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
931 } 884 }
932 } else if (klist->delkey < klist->nkeys) {
933 kdebug("replace %hu/%hu/%hu",
934 klist->delkey, klist->nkeys, klist->maxkeys);
935
936 discard = rcu_dereference_protected(
937 klist->keys[klist->delkey],
938 rwsem_is_locked(&keyring->sem));
939 rcu_assign_pointer(klist->keys[klist->delkey], key);
940 /* The garbage collector will take care of RCU
941 * synchronisation */
942 key_put(discard);
943 } else { 885 } else {
944 /* there's sufficient slack space to append directly */ 886 /* there's sufficient slack space to append directly */
945 kdebug("append %hu/%hu/%hu", 887 klist->keys[klist->nkeys] = key;
946 klist->delkey, klist->nkeys, klist->maxkeys);
947
948 RCU_INIT_POINTER(klist->keys[klist->delkey], key);
949 smp_wmb(); 888 smp_wmb();
950 klist->nkeys++; 889 klist->nkeys++;
951 } 890 }
@@ -959,7 +898,6 @@ void __key_link(struct key *keyring, struct key *key,
959void __key_link_end(struct key *keyring, struct key_type *type, 898void __key_link_end(struct key *keyring, struct key_type *type,
960 unsigned long prealloc) 899 unsigned long prealloc)
961 __releases(&keyring->sem) 900 __releases(&keyring->sem)
962 __releases(&keyring_serialise_link_sem)
963{ 901{
964 BUG_ON(type == NULL); 902 BUG_ON(type == NULL);
965 BUG_ON(type->name == NULL); 903 BUG_ON(type->name == NULL);
@@ -1053,7 +991,7 @@ int key_unlink(struct key *keyring, struct key *key)
1053 if (klist) { 991 if (klist) {
1054 /* search the keyring for the key */ 992 /* search the keyring for the key */
1055 for (loop = 0; loop < klist->nkeys; loop++) 993 for (loop = 0; loop < klist->nkeys; loop++)
1056 if (rcu_access_pointer(klist->keys[loop]) == key) 994 if (klist->keys[loop] == key)
1057 goto key_is_present; 995 goto key_is_present;
1058 } 996 }
1059 997
@@ -1116,7 +1054,7 @@ static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
1116 klist = container_of(rcu, struct keyring_list, rcu); 1054 klist = container_of(rcu, struct keyring_list, rcu);
1117 1055
1118 for (loop = klist->nkeys - 1; loop >= 0; loop--) 1056 for (loop = klist->nkeys - 1; loop >= 0; loop--)
1119 key_put(rcu_access_pointer(klist->keys[loop])); 1057 key_put(klist->keys[loop]);
1120 1058
1121 kfree(klist); 1059 kfree(klist);
1122} 1060}
@@ -1183,6 +1121,15 @@ static void keyring_revoke(struct key *keyring)
1183} 1121}
1184 1122
1185/* 1123/*
1124 * Determine whether a key is dead.
1125 */
1126static bool key_is_dead(struct key *key, time_t limit)
1127{
1128 return test_bit(KEY_FLAG_DEAD, &key->flags) ||
1129 (key->expiry > 0 && key->expiry <= limit);
1130}
1131
1132/*
1186 * Collect garbage from the contents of a keyring, replacing the old list with 1133 * Collect garbage from the contents of a keyring, replacing the old list with
1187 * a new one with the pointers all shuffled down. 1134 * a new one with the pointers all shuffled down.
1188 * 1135 *
@@ -1207,8 +1154,7 @@ void keyring_gc(struct key *keyring, time_t limit)
1207 /* work out how many subscriptions we're keeping */ 1154 /* work out how many subscriptions we're keeping */
1208 keep = 0; 1155 keep = 0;
1209 for (loop = klist->nkeys - 1; loop >= 0; loop--) 1156 for (loop = klist->nkeys - 1; loop >= 0; loop--)
1210 if (!key_is_dead(rcu_deref_link_locked(klist, loop, keyring), 1157 if (!key_is_dead(klist->keys[loop], limit))
1211 limit))
1212 keep++; 1158 keep++;
1213 1159
1214 if (keep == klist->nkeys) 1160 if (keep == klist->nkeys)
@@ -1229,11 +1175,11 @@ void keyring_gc(struct key *keyring, time_t limit)
1229 */ 1175 */
1230 keep = 0; 1176 keep = 0;
1231 for (loop = klist->nkeys - 1; loop >= 0; loop--) { 1177 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
1232 key = rcu_deref_link_locked(klist, loop, keyring); 1178 key = klist->keys[loop];
1233 if (!key_is_dead(key, limit)) { 1179 if (!key_is_dead(key, limit)) {
1234 if (keep >= max) 1180 if (keep >= max)
1235 goto discard_new; 1181 goto discard_new;
1236 RCU_INIT_POINTER(new->keys[keep++], key_get(key)); 1182 new->keys[keep++] = key_get(key);
1237 } 1183 }
1238 } 1184 }
1239 new->nkeys = keep; 1185 new->nkeys = keep;