diff options
author | David Howells <dhowells@redhat.com> | 2006-06-26 09:24:50 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 18:58:18 +0200 |
commit | 7e047ef5fe2d52e83020e856b1bf2556a6a2ce98 (patch) | |
tree | 97656e2c56a27be9d1da451dde627b693b8643f2 /security/keys/key.c | |
parent | [PATCH] fs: use list_move() (diff) | |
download | linux-7e047ef5fe2d52e83020e856b1bf2556a6a2ce98.tar.xz linux-7e047ef5fe2d52e83020e856b1bf2556a6a2ce98.zip |
[PATCH] keys: sort out key quota system
Add the ability for key creation to overrun the user's quota in some
circumstances - notably when a session keyring is created and assigned to a
process that didn't previously have one.
This means it's still possible to log in, should PAM require the creation of a
new session keyring, and fix an overburdened key quota.
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/key.c')
-rw-r--r-- | security/keys/key.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index 51f851557389..3601fddca9f2 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -248,7 +248,7 @@ static inline void key_alloc_serial(struct key *key) */ struct key *key_alloc(struct key_type *type, const char *desc, uid_t uid, gid_t gid, struct task_struct *ctx, - key_perm_t perm, int not_in_quota) + key_perm_t perm, unsigned long flags) { struct key_user *user = NULL; struct key *key; @@ -269,12 +269,14 @@ struct key *key_alloc(struct key_type *type, const char *desc, /* check that the user's quota permits allocation of another key and * its description */ - if (!not_in_quota) { + if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { spin_lock(&user->lock); - if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || - user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES - ) - goto no_quota; + if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) { + if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || + user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES + ) + goto no_quota; + } user->qnkeys++; user->qnbytes += quotalen; @@ -308,7 +310,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, key->payload.data = NULL; key->security = NULL; - if (!not_in_quota) + if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) key->flags |= 1 << KEY_FLAG_IN_QUOTA; memset(&key->type_data, 0, sizeof(key->type_data)); @@ -318,7 +320,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, #endif /* let the security module know about the key */ - ret = security_key_alloc(key, ctx); + ret = security_key_alloc(key, ctx, flags); if (ret < 0) goto security_error; @@ -332,7 +334,7 @@ error: security_error: kfree(key->description); kmem_cache_free(key_jar, key); - if (!not_in_quota) { + if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { spin_lock(&user->lock); user->qnkeys--; user->qnbytes -= quotalen; @@ -345,7 +347,7 @@ security_error: no_memory_3: kmem_cache_free(key_jar, key); no_memory_2: - if (!not_in_quota) { + if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { spin_lock(&user->lock); user->qnkeys--; user->qnbytes -= quotalen; @@ -761,7 +763,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, const char *description, const void *payload, size_t plen, - int not_in_quota) + unsigned long flags) { struct key_type *ktype; struct key *keyring, *key = NULL; @@ -822,7 +824,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, /* allocate a new key */ key = key_alloc(ktype, description, current->fsuid, current->fsgid, - current, perm, not_in_quota); + current, perm, flags); if (IS_ERR(key)) { key_ref = ERR_PTR(PTR_ERR(key)); goto error_3; |