diff options
author | David Howells <dhowells@redhat.com> | 2011-01-25 11:34:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-25 17:58:20 -0500 |
commit | ceb73c12047b8d543570b23353e7848eb7c540a1 (patch) | |
tree | a637dc88d418be1b705a66bea375af955bd14e22 /security/keys/key.c | |
parent | f5c66d70ac2a9016a7ad481bd37e39afd7dd7369 (diff) |
KEYS: Fix __key_link_end() quota fixup on error
Fix __key_link_end()'s attempt to fix up the quota if an error occurs.
There are two erroneous cases: Firstly, we always decrease the quota if
the preallocated replacement keyring needs cleaning up, irrespective of
whether or not we should (we may have replaced a pointer rather than
adding another pointer).
Secondly, we never clean up the quota if we added a pointer without the
keyring storage being extended (we allocate multiple pointers at a time,
even if we're not going to use them all immediately).
We handle this by setting the bottom bit of the preallocation pointer in
__key_link_begin() to indicate that the quota needs fixing up, which is
then passed to __key_link() (which clears the whole thing) and
__key_link_end().
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/keys/key.c')
-rw-r--r-- | security/keys/key.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index 84d4eb568b08..1c2d43dc5107 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -415,7 +415,7 @@ static int __key_instantiate_and_link(struct key *key, | |||
415 | size_t datalen, | 415 | size_t datalen, |
416 | struct key *keyring, | 416 | struct key *keyring, |
417 | struct key *authkey, | 417 | struct key *authkey, |
418 | struct keyring_list **_prealloc) | 418 | unsigned long *_prealloc) |
419 | { | 419 | { |
420 | int ret, awaken; | 420 | int ret, awaken; |
421 | 421 | ||
@@ -481,7 +481,7 @@ int key_instantiate_and_link(struct key *key, | |||
481 | struct key *keyring, | 481 | struct key *keyring, |
482 | struct key *authkey) | 482 | struct key *authkey) |
483 | { | 483 | { |
484 | struct keyring_list *prealloc; | 484 | unsigned long prealloc; |
485 | int ret; | 485 | int ret; |
486 | 486 | ||
487 | if (keyring) { | 487 | if (keyring) { |
@@ -526,7 +526,7 @@ int key_negate_and_link(struct key *key, | |||
526 | struct key *keyring, | 526 | struct key *keyring, |
527 | struct key *authkey) | 527 | struct key *authkey) |
528 | { | 528 | { |
529 | struct keyring_list *prealloc; | 529 | unsigned long prealloc; |
530 | struct timespec now; | 530 | struct timespec now; |
531 | int ret, awaken, link_ret = 0; | 531 | int ret, awaken, link_ret = 0; |
532 | 532 | ||
@@ -814,7 +814,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
814 | key_perm_t perm, | 814 | key_perm_t perm, |
815 | unsigned long flags) | 815 | unsigned long flags) |
816 | { | 816 | { |
817 | struct keyring_list *prealloc; | 817 | unsigned long prealloc; |
818 | const struct cred *cred = current_cred(); | 818 | const struct cred *cred = current_cred(); |
819 | struct key_type *ktype; | 819 | struct key_type *ktype; |
820 | struct key *keyring, *key = NULL; | 820 | struct key *keyring, *key = NULL; |