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/request_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/request_key.c')
-rw-r--r-- | security/keys/request_key.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index eab66a06ca53..58d1efd4fc2c 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -48,8 +48,8 @@ static int call_sbin_request_key(struct key *key, | |||
48 | /* allocate a new session keyring */ | 48 | /* allocate a new session keyring */ |
49 | sprintf(desc, "_req.%u", key->serial); | 49 | sprintf(desc, "_req.%u", key->serial); |
50 | 50 | ||
51 | keyring = keyring_alloc(desc, current->fsuid, current->fsgid, | 51 | keyring = keyring_alloc(desc, current->fsuid, current->fsgid, current, |
52 | current, 1, NULL); | 52 | KEY_ALLOC_QUOTA_OVERRUN, NULL); |
53 | if (IS_ERR(keyring)) { | 53 | if (IS_ERR(keyring)) { |
54 | ret = PTR_ERR(keyring); | 54 | ret = PTR_ERR(keyring); |
55 | goto error_alloc; | 55 | goto error_alloc; |
@@ -126,7 +126,8 @@ error_alloc: | |||
126 | */ | 126 | */ |
127 | static struct key *__request_key_construction(struct key_type *type, | 127 | static struct key *__request_key_construction(struct key_type *type, |
128 | const char *description, | 128 | const char *description, |
129 | const char *callout_info) | 129 | const char *callout_info, |
130 | unsigned long flags) | ||
130 | { | 131 | { |
131 | request_key_actor_t actor; | 132 | request_key_actor_t actor; |
132 | struct key_construction cons; | 133 | struct key_construction cons; |
@@ -134,12 +135,12 @@ static struct key *__request_key_construction(struct key_type *type, | |||
134 | struct key *key, *authkey; | 135 | struct key *key, *authkey; |
135 | int ret, negated; | 136 | int ret, negated; |
136 | 137 | ||
137 | kenter("%s,%s,%s", type->name, description, callout_info); | 138 | kenter("%s,%s,%s,%lx", type->name, description, callout_info, flags); |
138 | 139 | ||
139 | /* create a key and add it to the queue */ | 140 | /* create a key and add it to the queue */ |
140 | key = key_alloc(type, description, | 141 | key = key_alloc(type, description, |
141 | current->fsuid, current->fsgid, | 142 | current->fsuid, current->fsgid, current, KEY_POS_ALL, |
142 | current, KEY_POS_ALL, 0); | 143 | flags); |
143 | if (IS_ERR(key)) | 144 | if (IS_ERR(key)) |
144 | goto alloc_failed; | 145 | goto alloc_failed; |
145 | 146 | ||
@@ -258,15 +259,16 @@ alloc_failed: | |||
258 | static struct key *request_key_construction(struct key_type *type, | 259 | static struct key *request_key_construction(struct key_type *type, |
259 | const char *description, | 260 | const char *description, |
260 | struct key_user *user, | 261 | struct key_user *user, |
261 | const char *callout_info) | 262 | const char *callout_info, |
263 | unsigned long flags) | ||
262 | { | 264 | { |
263 | struct key_construction *pcons; | 265 | struct key_construction *pcons; |
264 | struct key *key, *ckey; | 266 | struct key *key, *ckey; |
265 | 267 | ||
266 | DECLARE_WAITQUEUE(myself, current); | 268 | DECLARE_WAITQUEUE(myself, current); |
267 | 269 | ||
268 | kenter("%s,%s,{%d},%s", | 270 | kenter("%s,%s,{%d},%s,%lx", |
269 | type->name, description, user->uid, callout_info); | 271 | type->name, description, user->uid, callout_info, flags); |
270 | 272 | ||
271 | /* see if there's such a key under construction already */ | 273 | /* see if there's such a key under construction already */ |
272 | down_write(&key_construction_sem); | 274 | down_write(&key_construction_sem); |
@@ -282,7 +284,8 @@ static struct key *request_key_construction(struct key_type *type, | |||
282 | } | 284 | } |
283 | 285 | ||
284 | /* see about getting userspace to construct the key */ | 286 | /* see about getting userspace to construct the key */ |
285 | key = __request_key_construction(type, description, callout_info); | 287 | key = __request_key_construction(type, description, callout_info, |
288 | flags); | ||
286 | error: | 289 | error: |
287 | kleave(" = %p", key); | 290 | kleave(" = %p", key); |
288 | return key; | 291 | return key; |
@@ -389,14 +392,15 @@ static void request_key_link(struct key *key, struct key *dest_keyring) | |||
389 | struct key *request_key_and_link(struct key_type *type, | 392 | struct key *request_key_and_link(struct key_type *type, |
390 | const char *description, | 393 | const char *description, |
391 | const char *callout_info, | 394 | const char *callout_info, |
392 | struct key *dest_keyring) | 395 | struct key *dest_keyring, |
396 | unsigned long flags) | ||
393 | { | 397 | { |
394 | struct key_user *user; | 398 | struct key_user *user; |
395 | struct key *key; | 399 | struct key *key; |
396 | key_ref_t key_ref; | 400 | key_ref_t key_ref; |
397 | 401 | ||
398 | kenter("%s,%s,%s,%p", | 402 | kenter("%s,%s,%s,%p,%lx", |
399 | type->name, description, callout_info, dest_keyring); | 403 | type->name, description, callout_info, dest_keyring, flags); |
400 | 404 | ||
401 | /* search all the process keyrings for a key */ | 405 | /* search all the process keyrings for a key */ |
402 | key_ref = search_process_keyrings(type, description, type->match, | 406 | key_ref = search_process_keyrings(type, description, type->match, |
@@ -429,7 +433,8 @@ struct key *request_key_and_link(struct key_type *type, | |||
429 | /* ask userspace (returns NULL if it waited on a key | 433 | /* ask userspace (returns NULL if it waited on a key |
430 | * being constructed) */ | 434 | * being constructed) */ |
431 | key = request_key_construction(type, description, | 435 | key = request_key_construction(type, description, |
432 | user, callout_info); | 436 | user, callout_info, |
437 | flags); | ||
433 | if (key) | 438 | if (key) |
434 | break; | 439 | break; |
435 | 440 | ||
@@ -485,7 +490,8 @@ struct key *request_key(struct key_type *type, | |||
485 | const char *description, | 490 | const char *description, |
486 | const char *callout_info) | 491 | const char *callout_info) |
487 | { | 492 | { |
488 | return request_key_and_link(type, description, callout_info, NULL); | 493 | return request_key_and_link(type, description, callout_info, NULL, |
494 | KEY_ALLOC_IN_QUOTA); | ||
489 | 495 | ||
490 | } /* end request_key() */ | 496 | } /* end request_key() */ |
491 | 497 | ||