diff options
author | Tejun Heo <tj@kernel.org> | 2011-02-21 09:43:56 +0100 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-02-21 09:43:56 +0100 |
commit | 43d133c18b44e7d82d82ef0dcc2bddd55d5dfe81 (patch) | |
tree | 8de75c837b55874cc8a81a29bdedbc62668d4481 /security/keys/keyring.c | |
parent | 4149efb22da66e326fc48baf80d628834509f7f0 (diff) | |
parent | 6f576d57f1fa0d6026b495d8746d56d949989161 (diff) |
Merge branch 'master' into for-2.6.39
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r-- | security/keys/keyring.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 92024ed12e0..5620f084ded 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -25,6 +25,8 @@ (keyring)->payload.subscriptions, \ rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem))) +#define KEY_LINK_FIXQUOTA 1UL + /* * When plumbing the depths of the key tree, this sets a hard limit * set on how deep we're willing to go. @@ -699,11 +701,11 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) * Preallocate memory so that a key can be linked into to a keyring. */ int __key_link_begin(struct key *keyring, const struct key_type *type, - const char *description, - struct keyring_list **_prealloc) + const char *description, unsigned long *_prealloc) __acquires(&keyring->sem) { struct keyring_list *klist, *nklist; + unsigned long prealloc; unsigned max; size_t size; int loop, ret; @@ -746,6 +748,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, /* note replacement slot */ klist->delkey = nklist->delkey = loop; + prealloc = (unsigned long)nklist; goto done; } } @@ -760,6 +763,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, if (klist && klist->nkeys < klist->maxkeys) { /* there's sufficient slack space to append directly */ nklist = NULL; + prealloc = KEY_LINK_FIXQUOTA; } else { /* grow the key list */ max = 4; @@ -794,8 +798,9 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, nklist->keys[nklist->delkey] = NULL; } + prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA; done: - *_prealloc = nklist; + *_prealloc = prealloc; kleave(" = 0"); return 0; @@ -836,12 +841,12 @@ int __key_link_check_live_key(struct key *keyring, struct key *key) * combination. */ void __key_link(struct key *keyring, struct key *key, - struct keyring_list **_prealloc) + unsigned long *_prealloc) { struct keyring_list *klist, *nklist; - nklist = *_prealloc; - *_prealloc = NULL; + nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA); + *_prealloc = 0; kenter("%d,%d,%p", keyring->serial, key->serial, nklist); @@ -881,20 +886,22 @@ void __key_link(struct key *keyring, struct key *key, * Must be called with __key_link_begin() having being called. */ void __key_link_end(struct key *keyring, struct key_type *type, - struct keyring_list *prealloc) + unsigned long prealloc) __releases(&keyring->sem) { BUG_ON(type == NULL); BUG_ON(type->name == NULL); - kenter("%d,%s,%p", keyring->serial, type->name, prealloc); + kenter("%d,%s,%lx", keyring->serial, type->name, prealloc); if (type == &key_type_keyring) up_write(&keyring_serialise_link_sem); if (prealloc) { - kfree(prealloc); - key_payload_reserve(keyring, - keyring->datalen - KEYQUOTA_LINK_BYTES); + if (prealloc & KEY_LINK_FIXQUOTA) + key_payload_reserve(keyring, + keyring->datalen - + KEYQUOTA_LINK_BYTES); + kfree((struct keyring_list *)(prealloc & ~KEY_LINK_FIXQUOTA)); } up_write(&keyring->sem); } @@ -921,7 +928,7 @@ void __key_link_end(struct key *keyring, struct key_type *type, */ int key_link(struct key *keyring, struct key *key) { - struct keyring_list *prealloc; + unsigned long prealloc; int ret; key_check(keyring); |