aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-06-26 03:24:50 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:18 -0400
commit7e047ef5fe2d52e83020e856b1bf2556a6a2ce98 (patch)
tree97656e2c56a27be9d1da451dde627b693b8643f2 /security/keys/key.c
parentf116629d03655adaf7832b93b03c99391d09d4a7 (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.c26
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 */
249struct key *key_alloc(struct key_type *type, const char *desc, 249struct 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:
332security_error: 334security_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:
345no_memory_3: 347no_memory_3:
346 kmem_cache_free(key_jar, key); 348 kmem_cache_free(key_jar, key);
347no_memory_2: 349no_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;