aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2005-06-24 01:00:49 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-24 03:05:18 -0400
commit76d8aeabfeb1c42641a81c44280177b9a08670d8 (patch)
tree0a584439bb44e440717aa77a1398ba9eea24a137 /security/keys/keyring.c
parent7286aa9b9ab35f20b1ff16d867f4535701df99b5 (diff)
[PATCH] keys: Discard key spinlock and use RCU for key payload
The attached patch changes the key implementation in a number of ways: (1) It removes the spinlock from the key structure. (2) The key flags are now accessed using atomic bitops instead of write-locking the key spinlock and using C bitwise operators. The three instantiation flags are dealt with with the construction semaphore held during the request_key/instantiate/negate sequence, thus rendering the spinlock superfluous. The key flags are also now bit numbers not bit masks. (3) The key payload is now accessed using RCU. This permits the recursive keyring search algorithm to be simplified greatly since no locks need be taken other than the usual RCU preemption disablement. Searching now does not require any locks or semaphores to be held; merely that the starting keyring be pinned. (4) The keyring payload now includes an RCU head so that it can be disposed of by call_rcu(). This requires that the payload be copied on unlink to prevent introducing races in copy-down vs search-up. (5) The user key payload is now a structure with the data following it. It includes an RCU head like the keyring payload and for the same reason. It also contains a data length because the data length in the key may be changed on another CPU whilst an RCU protected read is in progress on the payload. This would then see the supposed RCU payload and the on-key data length getting out of sync. I'm tempted to drop the key's datalen entirely, except that it's used in conjunction with quota management and so is a little tricky to get rid of. (6) Update the keys documentation. Signed-Off-By: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c245
1 files changed, 148 insertions, 97 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index e2ab4f8e7481..c9a5de197487 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -132,10 +132,17 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
132 (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key); 132 (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key);
133 133
134 ret = 0; 134 ret = 0;
135 sklist = source->payload.subscriptions;
136 135
137 if (sklist && sklist->nkeys > 0) { 136 /* find out how many keys are currently linked */
137 rcu_read_lock();
138 sklist = rcu_dereference(source->payload.subscriptions);
139 max = 0;
140 if (sklist)
138 max = sklist->nkeys; 141 max = sklist->nkeys;
142 rcu_read_unlock();
143
144 /* allocate a new payload and stuff load with key links */
145 if (max > 0) {
139 BUG_ON(max > limit); 146 BUG_ON(max > limit);
140 147
141 max = (max + 3) & ~3; 148 max = (max + 3) & ~3;
@@ -148,6 +155,10 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
148 if (!klist) 155 if (!klist)
149 goto error; 156 goto error;
150 157
158 /* set links */
159 rcu_read_lock();
160 sklist = rcu_dereference(source->payload.subscriptions);
161
151 klist->maxkeys = max; 162 klist->maxkeys = max;
152 klist->nkeys = sklist->nkeys; 163 klist->nkeys = sklist->nkeys;
153 memcpy(klist->keys, 164 memcpy(klist->keys,
@@ -157,7 +168,9 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
157 for (loop = klist->nkeys - 1; loop >= 0; loop--) 168 for (loop = klist->nkeys - 1; loop >= 0; loop--)
158 atomic_inc(&klist->keys[loop]->usage); 169 atomic_inc(&klist->keys[loop]->usage);
159 170
160 keyring->payload.subscriptions = klist; 171 rcu_read_unlock();
172
173 rcu_assign_pointer(keyring->payload.subscriptions, klist);
161 ret = 0; 174 ret = 0;
162 } 175 }
163 176
@@ -192,7 +205,7 @@ static void keyring_destroy(struct key *keyring)
192 write_unlock(&keyring_name_lock); 205 write_unlock(&keyring_name_lock);
193 } 206 }
194 207
195 klist = keyring->payload.subscriptions; 208 klist = rcu_dereference(keyring->payload.subscriptions);
196 if (klist) { 209 if (klist) {
197 for (loop = klist->nkeys - 1; loop >= 0; loop--) 210 for (loop = klist->nkeys - 1; loop >= 0; loop--)
198 key_put(klist->keys[loop]); 211 key_put(klist->keys[loop]);
@@ -216,17 +229,20 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
216 seq_puts(m, "[anon]"); 229 seq_puts(m, "[anon]");
217 } 230 }
218 231
219 klist = keyring->payload.subscriptions; 232 rcu_read_lock();
233 klist = rcu_dereference(keyring->payload.subscriptions);
220 if (klist) 234 if (klist)
221 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); 235 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
222 else 236 else
223 seq_puts(m, ": empty"); 237 seq_puts(m, ": empty");
238 rcu_read_unlock();
224 239
225} /* end keyring_describe() */ 240} /* end keyring_describe() */
226 241
227/*****************************************************************************/ 242/*****************************************************************************/
228/* 243/*
229 * read a list of key IDs from the keyring's contents 244 * read a list of key IDs from the keyring's contents
245 * - the keyring's semaphore is read-locked
230 */ 246 */
231static long keyring_read(const struct key *keyring, 247static long keyring_read(const struct key *keyring,
232 char __user *buffer, size_t buflen) 248 char __user *buffer, size_t buflen)
@@ -237,7 +253,7 @@ static long keyring_read(const struct key *keyring,
237 int loop, ret; 253 int loop, ret;
238 254
239 ret = 0; 255 ret = 0;
240 klist = keyring->payload.subscriptions; 256 klist = rcu_dereference(keyring->payload.subscriptions);
241 257
242 if (klist) { 258 if (klist) {
243 /* calculate how much data we could return */ 259 /* calculate how much data we could return */
@@ -320,7 +336,7 @@ struct key *keyring_search_aux(struct key *keyring,
320 key_match_func_t match) 336 key_match_func_t match)
321{ 337{
322 struct { 338 struct {
323 struct key *keyring; 339 struct keyring_list *keylist;
324 int kix; 340 int kix;
325 } stack[KEYRING_SEARCH_MAX_DEPTH]; 341 } stack[KEYRING_SEARCH_MAX_DEPTH];
326 342
@@ -328,10 +344,12 @@ struct key *keyring_search_aux(struct key *keyring,
328 struct timespec now; 344 struct timespec now;
329 struct key *key; 345 struct key *key;
330 long err; 346 long err;
331 int sp, psp, kix; 347 int sp, kix;
332 348
333 key_check(keyring); 349 key_check(keyring);
334 350
351 rcu_read_lock();
352
335 /* top keyring must have search permission to begin the search */ 353 /* top keyring must have search permission to begin the search */
336 key = ERR_PTR(-EACCES); 354 key = ERR_PTR(-EACCES);
337 if (!key_permission(keyring, KEY_SEARCH)) 355 if (!key_permission(keyring, KEY_SEARCH))
@@ -347,11 +365,10 @@ struct key *keyring_search_aux(struct key *keyring,
347 365
348 /* start processing a new keyring */ 366 /* start processing a new keyring */
349 descend: 367 descend:
350 read_lock(&keyring->lock); 368 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
351 if (keyring->flags & KEY_FLAG_REVOKED)
352 goto not_this_keyring; 369 goto not_this_keyring;
353 370
354 keylist = keyring->payload.subscriptions; 371 keylist = rcu_dereference(keyring->payload.subscriptions);
355 if (!keylist) 372 if (!keylist)
356 goto not_this_keyring; 373 goto not_this_keyring;
357 374
@@ -364,7 +381,7 @@ struct key *keyring_search_aux(struct key *keyring,
364 continue; 381 continue;
365 382
366 /* skip revoked keys and expired keys */ 383 /* skip revoked keys and expired keys */
367 if (key->flags & KEY_FLAG_REVOKED) 384 if (test_bit(KEY_FLAG_REVOKED, &key->flags))
368 continue; 385 continue;
369 386
370 if (key->expiry && now.tv_sec >= key->expiry) 387 if (key->expiry && now.tv_sec >= key->expiry)
@@ -379,7 +396,7 @@ struct key *keyring_search_aux(struct key *keyring,
379 continue; 396 continue;
380 397
381 /* we set a different error code if we find a negative key */ 398 /* we set a different error code if we find a negative key */
382 if (key->flags & KEY_FLAG_NEGATIVE) { 399 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
383 err = -ENOKEY; 400 err = -ENOKEY;
384 continue; 401 continue;
385 } 402 }
@@ -390,48 +407,37 @@ struct key *keyring_search_aux(struct key *keyring,
390 /* search through the keyrings nested in this one */ 407 /* search through the keyrings nested in this one */
391 kix = 0; 408 kix = 0;
392 ascend: 409 ascend:
393 while (kix < keylist->nkeys) { 410 for (; kix < keylist->nkeys; kix++) {
394 key = keylist->keys[kix]; 411 key = keylist->keys[kix];
395 if (key->type != &key_type_keyring) 412 if (key->type != &key_type_keyring)
396 goto next; 413 continue;
397 414
398 /* recursively search nested keyrings 415 /* recursively search nested keyrings
399 * - only search keyrings for which we have search permission 416 * - only search keyrings for which we have search permission
400 */ 417 */
401 if (sp >= KEYRING_SEARCH_MAX_DEPTH) 418 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
402 goto next; 419 continue;
403 420
404 if (!key_permission(key, KEY_SEARCH)) 421 if (!key_permission(key, KEY_SEARCH))
405 goto next; 422 continue;
406
407 /* evade loops in the keyring tree */
408 for (psp = 0; psp < sp; psp++)
409 if (stack[psp].keyring == keyring)
410 goto next;
411 423
412 /* stack the current position */ 424 /* stack the current position */
413 stack[sp].keyring = keyring; 425 stack[sp].keylist = keylist;
414 stack[sp].kix = kix; 426 stack[sp].kix = kix;
415 sp++; 427 sp++;
416 428
417 /* begin again with the new keyring */ 429 /* begin again with the new keyring */
418 keyring = key; 430 keyring = key;
419 goto descend; 431 goto descend;
420
421 next:
422 kix++;
423 } 432 }
424 433
425 /* the keyring we're looking at was disqualified or didn't contain a 434 /* the keyring we're looking at was disqualified or didn't contain a
426 * matching key */ 435 * matching key */
427 not_this_keyring: 436 not_this_keyring:
428 read_unlock(&keyring->lock);
429
430 if (sp > 0) { 437 if (sp > 0) {
431 /* resume the processing of a keyring higher up in the tree */ 438 /* resume the processing of a keyring higher up in the tree */
432 sp--; 439 sp--;
433 keyring = stack[sp].keyring; 440 keylist = stack[sp].keylist;
434 keylist = keyring->payload.subscriptions;
435 kix = stack[sp].kix + 1; 441 kix = stack[sp].kix + 1;
436 goto ascend; 442 goto ascend;
437 } 443 }
@@ -442,16 +448,9 @@ struct key *keyring_search_aux(struct key *keyring,
442 /* we found a viable match */ 448 /* we found a viable match */
443 found: 449 found:
444 atomic_inc(&key->usage); 450 atomic_inc(&key->usage);
445 read_unlock(&keyring->lock);
446
447 /* unwind the keyring stack */
448 while (sp > 0) {
449 sp--;
450 read_unlock(&stack[sp].keyring->lock);
451 }
452
453 key_check(key); 451 key_check(key);
454 error: 452 error:
453 rcu_read_unlock();
455 return key; 454 return key;
456 455
457} /* end keyring_search_aux() */ 456} /* end keyring_search_aux() */
@@ -489,7 +488,9 @@ struct key *__keyring_search_one(struct key *keyring,
489 struct key *key; 488 struct key *key;
490 int loop; 489 int loop;
491 490
492 klist = keyring->payload.subscriptions; 491 rcu_read_lock();
492
493 klist = rcu_dereference(keyring->payload.subscriptions);
493 if (klist) { 494 if (klist) {
494 for (loop = 0; loop < klist->nkeys; loop++) { 495 for (loop = 0; loop < klist->nkeys; loop++) {
495 key = klist->keys[loop]; 496 key = klist->keys[loop];
@@ -497,7 +498,7 @@ struct key *__keyring_search_one(struct key *keyring,
497 if (key->type == ktype && 498 if (key->type == ktype &&
498 key->type->match(key, description) && 499 key->type->match(key, description) &&
499 key_permission(key, perm) && 500 key_permission(key, perm) &&
500 !(key->flags & KEY_FLAG_REVOKED) 501 !test_bit(KEY_FLAG_REVOKED, &key->flags)
501 ) 502 )
502 goto found; 503 goto found;
503 } 504 }
@@ -509,6 +510,7 @@ struct key *__keyring_search_one(struct key *keyring,
509 found: 510 found:
510 atomic_inc(&key->usage); 511 atomic_inc(&key->usage);
511 error: 512 error:
513 rcu_read_unlock();
512 return key; 514 return key;
513 515
514} /* end __keyring_search_one() */ 516} /* end __keyring_search_one() */
@@ -540,7 +542,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
540 &keyring_name_hash[bucket], 542 &keyring_name_hash[bucket],
541 type_data.link 543 type_data.link
542 ) { 544 ) {
543 if (keyring->flags & KEY_FLAG_REVOKED) 545 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
544 continue; 546 continue;
545 547
546 if (strcmp(keyring->description, name) != 0) 548 if (strcmp(keyring->description, name) != 0)
@@ -579,7 +581,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
579static int keyring_detect_cycle(struct key *A, struct key *B) 581static int keyring_detect_cycle(struct key *A, struct key *B)
580{ 582{
581 struct { 583 struct {
582 struct key *subtree; 584 struct keyring_list *keylist;
583 int kix; 585 int kix;
584 } stack[KEYRING_SEARCH_MAX_DEPTH]; 586 } stack[KEYRING_SEARCH_MAX_DEPTH];
585 587
@@ -587,20 +589,21 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
587 struct key *subtree, *key; 589 struct key *subtree, *key;
588 int sp, kix, ret; 590 int sp, kix, ret;
589 591
592 rcu_read_lock();
593
590 ret = -EDEADLK; 594 ret = -EDEADLK;
591 if (A == B) 595 if (A == B)
592 goto error; 596 goto cycle_detected;
593 597
594 subtree = B; 598 subtree = B;
595 sp = 0; 599 sp = 0;
596 600
597 /* start processing a new keyring */ 601 /* start processing a new keyring */
598 descend: 602 descend:
599 read_lock(&subtree->lock); 603 if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
600 if (subtree->flags & KEY_FLAG_REVOKED)
601 goto not_this_keyring; 604 goto not_this_keyring;
602 605
603 keylist = subtree->payload.subscriptions; 606 keylist = rcu_dereference(subtree->payload.subscriptions);
604 if (!keylist) 607 if (!keylist)
605 goto not_this_keyring; 608 goto not_this_keyring;
606 kix = 0; 609 kix = 0;
@@ -619,7 +622,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
619 goto too_deep; 622 goto too_deep;
620 623
621 /* stack the current position */ 624 /* stack the current position */
622 stack[sp].subtree = subtree; 625 stack[sp].keylist = keylist;
623 stack[sp].kix = kix; 626 stack[sp].kix = kix;
624 sp++; 627 sp++;
625 628
@@ -632,13 +635,10 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
632 /* the keyring we're looking at was disqualified or didn't contain a 635 /* the keyring we're looking at was disqualified or didn't contain a
633 * matching key */ 636 * matching key */
634 not_this_keyring: 637 not_this_keyring:
635 read_unlock(&subtree->lock);
636
637 if (sp > 0) { 638 if (sp > 0) {
638 /* resume the checking of a keyring higher up in the tree */ 639 /* resume the checking of a keyring higher up in the tree */
639 sp--; 640 sp--;
640 subtree = stack[sp].subtree; 641 keylist = stack[sp].keylist;
641 keylist = subtree->payload.subscriptions;
642 kix = stack[sp].kix + 1; 642 kix = stack[sp].kix + 1;
643 goto ascend; 643 goto ascend;
644 } 644 }
@@ -646,30 +646,36 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
646 ret = 0; /* no cycles detected */ 646 ret = 0; /* no cycles detected */
647 647
648 error: 648 error:
649 rcu_read_unlock();
649 return ret; 650 return ret;
650 651
651 too_deep: 652 too_deep:
652 ret = -ELOOP; 653 ret = -ELOOP;
653 goto error_unwind; 654 goto error;
655
654 cycle_detected: 656 cycle_detected:
655 ret = -EDEADLK; 657 ret = -EDEADLK;
656 error_unwind:
657 read_unlock(&subtree->lock);
658
659 /* unwind the keyring stack */
660 while (sp > 0) {
661 sp--;
662 read_unlock(&stack[sp].subtree->lock);
663 }
664
665 goto error; 658 goto error;
666 659
667} /* end keyring_detect_cycle() */ 660} /* end keyring_detect_cycle() */
668 661
669/*****************************************************************************/ 662/*****************************************************************************/
670/* 663/*
664 * dispose of a keyring list after the RCU grace period
665 */
666static void keyring_link_rcu_disposal(struct rcu_head *rcu)
667{
668 struct keyring_list *klist =
669 container_of(rcu, struct keyring_list, rcu);
670
671 kfree(klist);
672
673} /* end keyring_link_rcu_disposal() */
674
675/*****************************************************************************/
676/*
671 * link a key into to a keyring 677 * link a key into to a keyring
672 * - must be called with the keyring's semaphore held 678 * - must be called with the keyring's semaphore write-locked
673 */ 679 */
674int __key_link(struct key *keyring, struct key *key) 680int __key_link(struct key *keyring, struct key *key)
675{ 681{
@@ -679,7 +685,7 @@ int __key_link(struct key *keyring, struct key *key)
679 int ret; 685 int ret;
680 686
681 ret = -EKEYREVOKED; 687 ret = -EKEYREVOKED;
682 if (keyring->flags & KEY_FLAG_REVOKED) 688 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
683 goto error; 689 goto error;
684 690
685 ret = -ENOTDIR; 691 ret = -ENOTDIR;
@@ -710,9 +716,10 @@ int __key_link(struct key *keyring, struct key *key)
710 /* there's sufficient slack space to add directly */ 716 /* there's sufficient slack space to add directly */
711 atomic_inc(&key->usage); 717 atomic_inc(&key->usage);
712 718
713 write_lock(&keyring->lock); 719 klist->keys[klist->nkeys] = key;
714 klist->keys[klist->nkeys++] = key; 720 smp_wmb();
715 write_unlock(&keyring->lock); 721 klist->nkeys++;
722 smp_wmb();
716 723
717 ret = 0; 724 ret = 0;
718 } 725 }
@@ -723,6 +730,8 @@ int __key_link(struct key *keyring, struct key *key)
723 max += klist->maxkeys; 730 max += klist->maxkeys;
724 731
725 ret = -ENFILE; 732 ret = -ENFILE;
733 if (max > 65535)
734 goto error3;
726 size = sizeof(*klist) + sizeof(*key) * max; 735 size = sizeof(*klist) + sizeof(*key) * max;
727 if (size > PAGE_SIZE) 736 if (size > PAGE_SIZE)
728 goto error3; 737 goto error3;
@@ -743,14 +752,13 @@ int __key_link(struct key *keyring, struct key *key)
743 752
744 /* add the key into the new space */ 753 /* add the key into the new space */
745 atomic_inc(&key->usage); 754 atomic_inc(&key->usage);
746
747 write_lock(&keyring->lock);
748 keyring->payload.subscriptions = nklist;
749 nklist->keys[nklist->nkeys++] = key; 755 nklist->keys[nklist->nkeys++] = key;
750 write_unlock(&keyring->lock); 756
757 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
751 758
752 /* dispose of the old keyring list */ 759 /* dispose of the old keyring list */
753 kfree(klist); 760 if (klist)
761 call_rcu(&klist->rcu, keyring_link_rcu_disposal);
754 762
755 ret = 0; 763 ret = 0;
756 } 764 }
@@ -791,11 +799,26 @@ EXPORT_SYMBOL(key_link);
791 799
792/*****************************************************************************/ 800/*****************************************************************************/
793/* 801/*
802 * dispose of a keyring list after the RCU grace period, freeing the unlinked
803 * key
804 */
805static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
806{
807 struct keyring_list *klist =
808 container_of(rcu, struct keyring_list, rcu);
809
810 key_put(klist->keys[klist->delkey]);
811 kfree(klist);
812
813} /* end keyring_unlink_rcu_disposal() */
814
815/*****************************************************************************/
816/*
794 * unlink the first link to a key from a keyring 817 * unlink the first link to a key from a keyring
795 */ 818 */
796int key_unlink(struct key *keyring, struct key *key) 819int key_unlink(struct key *keyring, struct key *key)
797{ 820{
798 struct keyring_list *klist; 821 struct keyring_list *klist, *nklist;
799 int loop, ret; 822 int loop, ret;
800 823
801 key_check(keyring); 824 key_check(keyring);
@@ -819,31 +842,45 @@ int key_unlink(struct key *keyring, struct key *key)
819 ret = -ENOENT; 842 ret = -ENOENT;
820 goto error; 843 goto error;
821 844
822 key_is_present: 845key_is_present:
846 /* we need to copy the key list for RCU purposes */
847 nklist = kmalloc(sizeof(*klist) + sizeof(*key) * klist->maxkeys,
848 GFP_KERNEL);
849 if (!nklist)
850 goto nomem;
851 nklist->maxkeys = klist->maxkeys;
852 nklist->nkeys = klist->nkeys - 1;
853
854 if (loop > 0)
855 memcpy(&nklist->keys[0],
856 &klist->keys[0],
857 loop * sizeof(klist->keys[0]));
858
859 if (loop < nklist->nkeys)
860 memcpy(&nklist->keys[loop],
861 &klist->keys[loop + 1],
862 (nklist->nkeys - loop) * sizeof(klist->keys[0]));
863
823 /* adjust the user's quota */ 864 /* adjust the user's quota */
824 key_payload_reserve(keyring, 865 key_payload_reserve(keyring,
825 keyring->datalen - KEYQUOTA_LINK_BYTES); 866 keyring->datalen - KEYQUOTA_LINK_BYTES);
826 867
827 /* shuffle down the key pointers 868 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
828 * - it might be worth shrinking the allocated memory, but that runs
829 * the risk of ENOMEM as we would have to copy
830 */
831 write_lock(&keyring->lock);
832 869
833 klist->nkeys--; 870 up_write(&keyring->sem);
834 if (loop < klist->nkeys)
835 memcpy(&klist->keys[loop],
836 &klist->keys[loop + 1],
837 (klist->nkeys - loop) * sizeof(struct key *));
838 871
839 write_unlock(&keyring->lock); 872 /* schedule for later cleanup */
873 klist->delkey = loop;
874 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
840 875
841 up_write(&keyring->sem);
842 key_put(key);
843 ret = 0; 876 ret = 0;
844 877
845 error: 878error:
846 return ret; 879 return ret;
880nomem:
881 ret = -ENOMEM;
882 up_write(&keyring->sem);
883 goto error;
847 884
848} /* end key_unlink() */ 885} /* end key_unlink() */
849 886
@@ -851,13 +888,32 @@ EXPORT_SYMBOL(key_unlink);
851 888
852/*****************************************************************************/ 889/*****************************************************************************/
853/* 890/*
891 * dispose of a keyring list after the RCU grace period, releasing the keys it
892 * links to
893 */
894static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
895{
896 struct keyring_list *klist;
897 int loop;
898
899 klist = container_of(rcu, struct keyring_list, rcu);
900
901 for (loop = klist->nkeys - 1; loop >= 0; loop--)
902 key_put(klist->keys[loop]);
903
904 kfree(klist);
905
906} /* end keyring_clear_rcu_disposal() */
907
908/*****************************************************************************/
909/*
854 * clear the specified process keyring 910 * clear the specified process keyring
855 * - implements keyctl(KEYCTL_CLEAR) 911 * - implements keyctl(KEYCTL_CLEAR)
856 */ 912 */
857int keyring_clear(struct key *keyring) 913int keyring_clear(struct key *keyring)
858{ 914{
859 struct keyring_list *klist; 915 struct keyring_list *klist;
860 int loop, ret; 916 int ret;
861 917
862 ret = -ENOTDIR; 918 ret = -ENOTDIR;
863 if (keyring->type == &key_type_keyring) { 919 if (keyring->type == &key_type_keyring) {
@@ -870,20 +926,15 @@ int keyring_clear(struct key *keyring)
870 key_payload_reserve(keyring, 926 key_payload_reserve(keyring,
871 sizeof(struct keyring_list)); 927 sizeof(struct keyring_list));
872 928
873 write_lock(&keyring->lock); 929 rcu_assign_pointer(keyring->payload.subscriptions,
874 keyring->payload.subscriptions = NULL; 930 NULL);
875 write_unlock(&keyring->lock);
876 } 931 }
877 932
878 up_write(&keyring->sem); 933 up_write(&keyring->sem);
879 934
880 /* free the keys after the locks have been dropped */ 935 /* free the keys after the locks have been dropped */
881 if (klist) { 936 if (klist)
882 for (loop = klist->nkeys - 1; loop >= 0; loop--) 937 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
883 key_put(klist->keys[loop]);
884
885 kfree(klist);
886 }
887 938
888 ret = 0; 939 ret = 0;
889 } 940 }