diff options
author | David Howells <dhowells@redhat.com> | 2006-06-26 03:24:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:18 -0400 |
commit | 7e047ef5fe2d52e83020e856b1bf2556a6a2ce98 (patch) | |
tree | 97656e2c56a27be9d1da451dde627b693b8643f2 /security/keys/key.c | |
parent | f116629d03655adaf7832b93b03c99391d09d4a7 (diff) |
[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) | |||
248 | */ | 248 | */ |
249 | struct key *key_alloc(struct key_type *type, const char *desc, | 249 | struct key *key_alloc(struct key_type *type, const char *desc, |
250 | uid_t uid, gid_t gid, struct task_struct *ctx, | 250 | uid_t uid, gid_t gid, struct task_struct *ctx, |
251 | key_perm_t perm, int not_in_quota) | 251 | key_perm_t perm, unsigned long flags) |
252 | { | 252 | { |
253 | struct key_user *user = NULL; | 253 | struct key_user *user = NULL; |
254 | struct key *key; | 254 | struct key *key; |
@@ -269,12 +269,14 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
269 | 269 | ||
270 | /* check that the user's quota permits allocation of another key and | 270 | /* check that the user's quota permits allocation of another key and |
271 | * its description */ | 271 | * its description */ |
272 | if (!not_in_quota) { | 272 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { |
273 | spin_lock(&user->lock); | 273 | spin_lock(&user->lock); |
274 | if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || | 274 | if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) { |
275 | user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES | 275 | if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || |
276 | ) | 276 | user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES |
277 | goto no_quota; | 277 | ) |
278 | goto no_quota; | ||
279 | } | ||
278 | 280 | ||
279 | user->qnkeys++; | 281 | user->qnkeys++; |
280 | user->qnbytes += quotalen; | 282 | user->qnbytes += quotalen; |
@@ -308,7 +310,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
308 | key->payload.data = NULL; | 310 | key->payload.data = NULL; |
309 | key->security = NULL; | 311 | key->security = NULL; |
310 | 312 | ||
311 | if (!not_in_quota) | 313 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) |
312 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; | 314 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; |
313 | 315 | ||
314 | memset(&key->type_data, 0, sizeof(key->type_data)); | 316 | memset(&key->type_data, 0, sizeof(key->type_data)); |
@@ -318,7 +320,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
318 | #endif | 320 | #endif |
319 | 321 | ||
320 | /* let the security module know about the key */ | 322 | /* let the security module know about the key */ |
321 | ret = security_key_alloc(key, ctx); | 323 | ret = security_key_alloc(key, ctx, flags); |
322 | if (ret < 0) | 324 | if (ret < 0) |
323 | goto security_error; | 325 | goto security_error; |
324 | 326 | ||
@@ -332,7 +334,7 @@ error: | |||
332 | security_error: | 334 | security_error: |
333 | kfree(key->description); | 335 | kfree(key->description); |
334 | kmem_cache_free(key_jar, key); | 336 | kmem_cache_free(key_jar, key); |
335 | if (!not_in_quota) { | 337 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { |
336 | spin_lock(&user->lock); | 338 | spin_lock(&user->lock); |
337 | user->qnkeys--; | 339 | user->qnkeys--; |
338 | user->qnbytes -= quotalen; | 340 | user->qnbytes -= quotalen; |
@@ -345,7 +347,7 @@ security_error: | |||
345 | no_memory_3: | 347 | no_memory_3: |
346 | kmem_cache_free(key_jar, key); | 348 | kmem_cache_free(key_jar, key); |
347 | no_memory_2: | 349 | no_memory_2: |
348 | if (!not_in_quota) { | 350 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { |
349 | spin_lock(&user->lock); | 351 | spin_lock(&user->lock); |
350 | user->qnkeys--; | 352 | user->qnkeys--; |
351 | user->qnbytes -= quotalen; | 353 | user->qnbytes -= quotalen; |
@@ -761,7 +763,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
761 | const char *description, | 763 | const char *description, |
762 | const void *payload, | 764 | const void *payload, |
763 | size_t plen, | 765 | size_t plen, |
764 | int not_in_quota) | 766 | unsigned long flags) |
765 | { | 767 | { |
766 | struct key_type *ktype; | 768 | struct key_type *ktype; |
767 | struct key *keyring, *key = NULL; | 769 | struct key *keyring, *key = NULL; |
@@ -822,7 +824,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
822 | 824 | ||
823 | /* allocate a new key */ | 825 | /* allocate a new key */ |
824 | key = key_alloc(ktype, description, current->fsuid, current->fsgid, | 826 | key = key_alloc(ktype, description, current->fsuid, current->fsgid, |
825 | current, perm, not_in_quota); | 827 | current, perm, flags); |
826 | if (IS_ERR(key)) { | 828 | if (IS_ERR(key)) { |
827 | key_ref = ERR_PTR(PTR_ERR(key)); | 829 | key_ref = ERR_PTR(PTR_ERR(key)); |
828 | goto error_3; | 830 | goto error_3; |