|
@@ -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);
|