diff options
| author | David Howells <dhowells@redhat.com> | 2008-04-29 04:01:24 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 11:06:16 -0400 |
| commit | 4a38e122e2cc6294779021ff4ccc784a3997059e (patch) | |
| tree | 84b401b44e0550b04f831d98a91eacfd7cffb51d /security/keys | |
| parent | dceba9944181b1fd5993417b5c8fa0e3dda38f8d (diff) | |
keys: allow the callout data to be passed as a blob rather than a string
Allow the callout data to be passed as a blob rather than a string for
internal kernel services that call any request_key_*() interface other than
request_key(). request_key() itself still takes a NUL-terminated string.
The functions that change are:
request_key_with_auxdata()
request_key_async()
request_key_async_with_auxdata()
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Paul Moore <paul.moore@hp.com>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: James Morris <jmorris@namei.org>
Cc: Kevin Coffman <kwc@citi.umich.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/keys')
| -rw-r--r-- | security/keys/internal.h | 9 | ||||
| -rw-r--r-- | security/keys/keyctl.c | 7 | ||||
| -rw-r--r-- | security/keys/request_key.c | 49 | ||||
| -rw-r--r-- | security/keys/request_key_auth.c | 12 |
4 files changed, 48 insertions, 29 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h index 7d894ef70370..3cc04c2afe1c 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
| @@ -109,7 +109,8 @@ extern int install_process_keyring(struct task_struct *tsk); | |||
| 109 | 109 | ||
| 110 | extern struct key *request_key_and_link(struct key_type *type, | 110 | extern struct key *request_key_and_link(struct key_type *type, |
| 111 | const char *description, | 111 | const char *description, |
| 112 | const char *callout_info, | 112 | const void *callout_info, |
| 113 | size_t callout_len, | ||
| 113 | void *aux, | 114 | void *aux, |
| 114 | struct key *dest_keyring, | 115 | struct key *dest_keyring, |
| 115 | unsigned long flags); | 116 | unsigned long flags); |
| @@ -120,13 +121,15 @@ extern struct key *request_key_and_link(struct key_type *type, | |||
| 120 | struct request_key_auth { | 121 | struct request_key_auth { |
| 121 | struct key *target_key; | 122 | struct key *target_key; |
| 122 | struct task_struct *context; | 123 | struct task_struct *context; |
| 123 | char *callout_info; | 124 | void *callout_info; |
| 125 | size_t callout_len; | ||
| 124 | pid_t pid; | 126 | pid_t pid; |
| 125 | }; | 127 | }; |
| 126 | 128 | ||
| 127 | extern struct key_type key_type_request_key_auth; | 129 | extern struct key_type key_type_request_key_auth; |
| 128 | extern struct key *request_key_auth_new(struct key *target, | 130 | extern struct key *request_key_auth_new(struct key *target, |
| 129 | const char *callout_info); | 131 | const void *callout_info, |
| 132 | size_t callout_len); | ||
| 130 | 133 | ||
| 131 | extern struct key *key_get_instantiation_authkey(key_serial_t target_id); | 134 | extern struct key *key_get_instantiation_authkey(key_serial_t target_id); |
| 132 | 135 | ||
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 8ec84326a983..1698bf90ee84 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -152,6 +152,7 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
| 152 | struct key_type *ktype; | 152 | struct key_type *ktype; |
| 153 | struct key *key; | 153 | struct key *key; |
| 154 | key_ref_t dest_ref; | 154 | key_ref_t dest_ref; |
| 155 | size_t callout_len; | ||
| 155 | char type[32], *description, *callout_info; | 156 | char type[32], *description, *callout_info; |
| 156 | long ret; | 157 | long ret; |
| 157 | 158 | ||
| @@ -169,12 +170,14 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
| 169 | 170 | ||
| 170 | /* pull the callout info into kernel space */ | 171 | /* pull the callout info into kernel space */ |
| 171 | callout_info = NULL; | 172 | callout_info = NULL; |
| 173 | callout_len = 0; | ||
| 172 | if (_callout_info) { | 174 | if (_callout_info) { |
| 173 | callout_info = strndup_user(_callout_info, PAGE_SIZE); | 175 | callout_info = strndup_user(_callout_info, PAGE_SIZE); |
| 174 | if (IS_ERR(callout_info)) { | 176 | if (IS_ERR(callout_info)) { |
| 175 | ret = PTR_ERR(callout_info); | 177 | ret = PTR_ERR(callout_info); |
| 176 | goto error2; | 178 | goto error2; |
| 177 | } | 179 | } |
| 180 | callout_len = strlen(callout_info); | ||
| 178 | } | 181 | } |
| 179 | 182 | ||
| 180 | /* get the destination keyring if specified */ | 183 | /* get the destination keyring if specified */ |
| @@ -195,8 +198,8 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
| 195 | } | 198 | } |
| 196 | 199 | ||
| 197 | /* do the search */ | 200 | /* do the search */ |
| 198 | key = request_key_and_link(ktype, description, callout_info, NULL, | 201 | key = request_key_and_link(ktype, description, callout_info, |
| 199 | key_ref_to_ptr(dest_ref), | 202 | callout_len, NULL, key_ref_to_ptr(dest_ref), |
| 200 | KEY_ALLOC_IN_QUOTA); | 203 | KEY_ALLOC_IN_QUOTA); |
| 201 | if (IS_ERR(key)) { | 204 | if (IS_ERR(key)) { |
| 202 | ret = PTR_ERR(key); | 205 | ret = PTR_ERR(key); |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 5ecc5057fb54..a3f94c60692d 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
| @@ -161,21 +161,22 @@ error_alloc: | |||
| 161 | * call out to userspace for key construction | 161 | * call out to userspace for key construction |
| 162 | * - we ignore program failure and go on key status instead | 162 | * - we ignore program failure and go on key status instead |
| 163 | */ | 163 | */ |
| 164 | static int construct_key(struct key *key, const char *callout_info, void *aux) | 164 | static int construct_key(struct key *key, const void *callout_info, |
| 165 | size_t callout_len, void *aux) | ||
| 165 | { | 166 | { |
| 166 | struct key_construction *cons; | 167 | struct key_construction *cons; |
| 167 | request_key_actor_t actor; | 168 | request_key_actor_t actor; |
| 168 | struct key *authkey; | 169 | struct key *authkey; |
| 169 | int ret; | 170 | int ret; |
| 170 | 171 | ||
| 171 | kenter("%d,%s,%p", key->serial, callout_info, aux); | 172 | kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); |
| 172 | 173 | ||
| 173 | cons = kmalloc(sizeof(*cons), GFP_KERNEL); | 174 | cons = kmalloc(sizeof(*cons), GFP_KERNEL); |
| 174 | if (!cons) | 175 | if (!cons) |
| 175 | return -ENOMEM; | 176 | return -ENOMEM; |
| 176 | 177 | ||
| 177 | /* allocate an authorisation key */ | 178 | /* allocate an authorisation key */ |
| 178 | authkey = request_key_auth_new(key, callout_info); | 179 | authkey = request_key_auth_new(key, callout_info, callout_len); |
| 179 | if (IS_ERR(authkey)) { | 180 | if (IS_ERR(authkey)) { |
| 180 | kfree(cons); | 181 | kfree(cons); |
| 181 | ret = PTR_ERR(authkey); | 182 | ret = PTR_ERR(authkey); |
| @@ -331,6 +332,7 @@ alloc_failed: | |||
| 331 | static struct key *construct_key_and_link(struct key_type *type, | 332 | static struct key *construct_key_and_link(struct key_type *type, |
| 332 | const char *description, | 333 | const char *description, |
| 333 | const char *callout_info, | 334 | const char *callout_info, |
| 335 | size_t callout_len, | ||
| 334 | void *aux, | 336 | void *aux, |
| 335 | struct key *dest_keyring, | 337 | struct key *dest_keyring, |
| 336 | unsigned long flags) | 338 | unsigned long flags) |
| @@ -348,7 +350,7 @@ static struct key *construct_key_and_link(struct key_type *type, | |||
| 348 | key_user_put(user); | 350 | key_user_put(user); |
| 349 | 351 | ||
| 350 | if (ret == 0) { | 352 | if (ret == 0) { |
| 351 | ret = construct_key(key, callout_info, aux); | 353 | ret = construct_key(key, callout_info, callout_len, aux); |
| 352 | if (ret < 0) | 354 | if (ret < 0) |
| 353 | goto construction_failed; | 355 | goto construction_failed; |
| 354 | } | 356 | } |
| @@ -370,7 +372,8 @@ construction_failed: | |||
| 370 | */ | 372 | */ |
| 371 | struct key *request_key_and_link(struct key_type *type, | 373 | struct key *request_key_and_link(struct key_type *type, |
| 372 | const char *description, | 374 | const char *description, |
| 373 | const char *callout_info, | 375 | const void *callout_info, |
| 376 | size_t callout_len, | ||
| 374 | void *aux, | 377 | void *aux, |
| 375 | struct key *dest_keyring, | 378 | struct key *dest_keyring, |
| 376 | unsigned long flags) | 379 | unsigned long flags) |
| @@ -378,8 +381,8 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 378 | struct key *key; | 381 | struct key *key; |
| 379 | key_ref_t key_ref; | 382 | key_ref_t key_ref; |
| 380 | 383 | ||
| 381 | kenter("%s,%s,%s,%p,%p,%lx", | 384 | kenter("%s,%s,%p,%zu,%p,%p,%lx", |
| 382 | type->name, description, callout_info, aux, | 385 | type->name, description, callout_info, callout_len, aux, |
| 383 | dest_keyring, flags); | 386 | dest_keyring, flags); |
| 384 | 387 | ||
| 385 | /* search all the process keyrings for a key */ | 388 | /* search all the process keyrings for a key */ |
| @@ -398,7 +401,8 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 398 | goto error; | 401 | goto error; |
| 399 | 402 | ||
| 400 | key = construct_key_and_link(type, description, callout_info, | 403 | key = construct_key_and_link(type, description, callout_info, |
| 401 | aux, dest_keyring, flags); | 404 | callout_len, aux, dest_keyring, |
| 405 | flags); | ||
| 402 | } | 406 | } |
| 403 | 407 | ||
| 404 | error: | 408 | error: |
| @@ -434,10 +438,13 @@ struct key *request_key(struct key_type *type, | |||
| 434 | const char *callout_info) | 438 | const char *callout_info) |
| 435 | { | 439 | { |
| 436 | struct key *key; | 440 | struct key *key; |
| 441 | size_t callout_len = 0; | ||
| 437 | int ret; | 442 | int ret; |
| 438 | 443 | ||
| 439 | key = request_key_and_link(type, description, callout_info, NULL, | 444 | if (callout_info) |
| 440 | NULL, KEY_ALLOC_IN_QUOTA); | 445 | callout_len = strlen(callout_info); |
| 446 | key = request_key_and_link(type, description, callout_info, callout_len, | ||
| 447 | NULL, NULL, KEY_ALLOC_IN_QUOTA); | ||
| 441 | if (!IS_ERR(key)) { | 448 | if (!IS_ERR(key)) { |
| 442 | ret = wait_for_key_construction(key, false); | 449 | ret = wait_for_key_construction(key, false); |
| 443 | if (ret < 0) { | 450 | if (ret < 0) { |
| @@ -458,14 +465,15 @@ EXPORT_SYMBOL(request_key); | |||
| 458 | */ | 465 | */ |
| 459 | struct key *request_key_with_auxdata(struct key_type *type, | 466 | struct key *request_key_with_auxdata(struct key_type *type, |
| 460 | const char *description, | 467 | const char *description, |
| 461 | const char *callout_info, | 468 | const void *callout_info, |
| 469 | size_t callout_len, | ||
| 462 | void *aux) | 470 | void *aux) |
| 463 | { | 471 | { |
| 464 | struct key *key; | 472 | struct key *key; |
| 465 | int ret; | 473 | int ret; |
| 466 | 474 | ||
| 467 | key = request_key_and_link(type, description, callout_info, aux, | 475 | key = request_key_and_link(type, description, callout_info, callout_len, |
| 468 | NULL, KEY_ALLOC_IN_QUOTA); | 476 | aux, NULL, KEY_ALLOC_IN_QUOTA); |
| 469 | if (!IS_ERR(key)) { | 477 | if (!IS_ERR(key)) { |
| 470 | ret = wait_for_key_construction(key, false); | 478 | ret = wait_for_key_construction(key, false); |
| 471 | if (ret < 0) { | 479 | if (ret < 0) { |
| @@ -485,10 +493,12 @@ EXPORT_SYMBOL(request_key_with_auxdata); | |||
| 485 | */ | 493 | */ |
| 486 | struct key *request_key_async(struct key_type *type, | 494 | struct key *request_key_async(struct key_type *type, |
| 487 | const char *description, | 495 | const char *description, |
| 488 | const char *callout_info) | 496 | const void *callout_info, |
| 497 | size_t callout_len) | ||
| 489 | { | 498 | { |
| 490 | return request_key_and_link(type, description, callout_info, NULL, | 499 | return request_key_and_link(type, description, callout_info, |
| 491 | NULL, KEY_ALLOC_IN_QUOTA); | 500 | callout_len, NULL, NULL, |
| 501 | KEY_ALLOC_IN_QUOTA); | ||
| 492 | } | 502 | } |
| 493 | EXPORT_SYMBOL(request_key_async); | 503 | EXPORT_SYMBOL(request_key_async); |
| 494 | 504 | ||
| @@ -500,10 +510,11 @@ EXPORT_SYMBOL(request_key_async); | |||
| 500 | */ | 510 | */ |
| 501 | struct key *request_key_async_with_auxdata(struct key_type *type, | 511 | struct key *request_key_async_with_auxdata(struct key_type *type, |
| 502 | const char *description, | 512 | const char *description, |
| 503 | const char *callout_info, | 513 | const void *callout_info, |
| 514 | size_t callout_len, | ||
| 504 | void *aux) | 515 | void *aux) |
| 505 | { | 516 | { |
| 506 | return request_key_and_link(type, description, callout_info, aux, | 517 | return request_key_and_link(type, description, callout_info, |
| 507 | NULL, KEY_ALLOC_IN_QUOTA); | 518 | callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA); |
| 508 | } | 519 | } |
| 509 | EXPORT_SYMBOL(request_key_async_with_auxdata); | 520 | EXPORT_SYMBOL(request_key_async_with_auxdata); |
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index e42b5252486f..c615d473ce7c 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
| @@ -61,7 +61,7 @@ static void request_key_auth_describe(const struct key *key, | |||
| 61 | 61 | ||
| 62 | seq_puts(m, "key:"); | 62 | seq_puts(m, "key:"); |
| 63 | seq_puts(m, key->description); | 63 | seq_puts(m, key->description); |
| 64 | seq_printf(m, " pid:%d ci:%zu", rka->pid, strlen(rka->callout_info)); | 64 | seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); |
| 65 | 65 | ||
| 66 | } /* end request_key_auth_describe() */ | 66 | } /* end request_key_auth_describe() */ |
| 67 | 67 | ||
| @@ -77,7 +77,7 @@ static long request_key_auth_read(const struct key *key, | |||
| 77 | size_t datalen; | 77 | size_t datalen; |
| 78 | long ret; | 78 | long ret; |
| 79 | 79 | ||
| 80 | datalen = strlen(rka->callout_info); | 80 | datalen = rka->callout_len; |
| 81 | ret = datalen; | 81 | ret = datalen; |
| 82 | 82 | ||
| 83 | /* we can return the data as is */ | 83 | /* we can return the data as is */ |
| @@ -137,7 +137,8 @@ static void request_key_auth_destroy(struct key *key) | |||
| 137 | * create an authorisation token for /sbin/request-key or whoever to gain | 137 | * create an authorisation token for /sbin/request-key or whoever to gain |
| 138 | * access to the caller's security data | 138 | * access to the caller's security data |
| 139 | */ | 139 | */ |
| 140 | struct key *request_key_auth_new(struct key *target, const char *callout_info) | 140 | struct key *request_key_auth_new(struct key *target, const void *callout_info, |
| 141 | size_t callout_len) | ||
| 141 | { | 142 | { |
| 142 | struct request_key_auth *rka, *irka; | 143 | struct request_key_auth *rka, *irka; |
| 143 | struct key *authkey = NULL; | 144 | struct key *authkey = NULL; |
| @@ -152,7 +153,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
| 152 | kleave(" = -ENOMEM"); | 153 | kleave(" = -ENOMEM"); |
| 153 | return ERR_PTR(-ENOMEM); | 154 | return ERR_PTR(-ENOMEM); |
| 154 | } | 155 | } |
| 155 | rka->callout_info = kmalloc(strlen(callout_info) + 1, GFP_KERNEL); | 156 | rka->callout_info = kmalloc(callout_len, GFP_KERNEL); |
| 156 | if (!rka->callout_info) { | 157 | if (!rka->callout_info) { |
| 157 | kleave(" = -ENOMEM"); | 158 | kleave(" = -ENOMEM"); |
| 158 | kfree(rka); | 159 | kfree(rka); |
| @@ -186,7 +187,8 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
| 186 | } | 187 | } |
| 187 | 188 | ||
| 188 | rka->target_key = key_get(target); | 189 | rka->target_key = key_get(target); |
| 189 | strcpy(rka->callout_info, callout_info); | 190 | memcpy(rka->callout_info, callout_info, callout_len); |
| 191 | rka->callout_len = callout_len; | ||
| 190 | 192 | ||
| 191 | /* allocate the auth key */ | 193 | /* allocate the auth key */ |
| 192 | sprintf(desc, "%x", target->serial); | 194 | sprintf(desc, "%x", target->serial); |
