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 | |
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>
-rw-r--r-- | Documentation/keys-request-key.txt | 11 | ||||
-rw-r--r-- | Documentation/keys.txt | 14 | ||||
-rw-r--r-- | include/linux/key.h | 9 | ||||
-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 |
7 files changed, 70 insertions, 41 deletions
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt index 266955d23ee6..09b55e461740 100644 --- a/Documentation/keys-request-key.txt +++ b/Documentation/keys-request-key.txt | |||
@@ -11,26 +11,29 @@ request_key*(): | |||
11 | 11 | ||
12 | struct key *request_key(const struct key_type *type, | 12 | struct key *request_key(const struct key_type *type, |
13 | const char *description, | 13 | const char *description, |
14 | const char *callout_string); | 14 | const char *callout_info); |
15 | 15 | ||
16 | or: | 16 | or: |
17 | 17 | ||
18 | struct key *request_key_with_auxdata(const struct key_type *type, | 18 | struct key *request_key_with_auxdata(const struct key_type *type, |
19 | const char *description, | 19 | const char *description, |
20 | const char *callout_string, | 20 | const char *callout_info, |
21 | size_t callout_len, | ||
21 | void *aux); | 22 | void *aux); |
22 | 23 | ||
23 | or: | 24 | or: |
24 | 25 | ||
25 | struct key *request_key_async(const struct key_type *type, | 26 | struct key *request_key_async(const struct key_type *type, |
26 | const char *description, | 27 | const char *description, |
27 | const char *callout_string); | 28 | const char *callout_info, |
29 | size_t callout_len); | ||
28 | 30 | ||
29 | or: | 31 | or: |
30 | 32 | ||
31 | struct key *request_key_async_with_auxdata(const struct key_type *type, | 33 | struct key *request_key_async_with_auxdata(const struct key_type *type, |
32 | const char *description, | 34 | const char *description, |
33 | const char *callout_string, | 35 | const char *callout_info, |
36 | size_t callout_len, | ||
34 | void *aux); | 37 | void *aux); |
35 | 38 | ||
36 | Or by userspace invoking the request_key system call: | 39 | Or by userspace invoking the request_key system call: |
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index 51652d39e61c..b82d38de8b89 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
@@ -771,7 +771,7 @@ payload contents" for more information. | |||
771 | 771 | ||
772 | struct key *request_key(const struct key_type *type, | 772 | struct key *request_key(const struct key_type *type, |
773 | const char *description, | 773 | const char *description, |
774 | const char *callout_string); | 774 | const char *callout_info); |
775 | 775 | ||
776 | This is used to request a key or keyring with a description that matches | 776 | This is used to request a key or keyring with a description that matches |
777 | the description specified according to the key type's match function. This | 777 | the description specified according to the key type's match function. This |
@@ -793,24 +793,28 @@ payload contents" for more information. | |||
793 | 793 | ||
794 | struct key *request_key_with_auxdata(const struct key_type *type, | 794 | struct key *request_key_with_auxdata(const struct key_type *type, |
795 | const char *description, | 795 | const char *description, |
796 | const char *callout_string, | 796 | const void *callout_info, |
797 | size_t callout_len, | ||
797 | void *aux); | 798 | void *aux); |
798 | 799 | ||
799 | This is identical to request_key(), except that the auxiliary data is | 800 | This is identical to request_key(), except that the auxiliary data is |
800 | passed to the key_type->request_key() op if it exists. | 801 | passed to the key_type->request_key() op if it exists, and the callout_info |
802 | is a blob of length callout_len, if given (the length may be 0). | ||
801 | 803 | ||
802 | 804 | ||
803 | (*) A key can be requested asynchronously by calling one of: | 805 | (*) A key can be requested asynchronously by calling one of: |
804 | 806 | ||
805 | struct key *request_key_async(const struct key_type *type, | 807 | struct key *request_key_async(const struct key_type *type, |
806 | const char *description, | 808 | const char *description, |
807 | const char *callout_string); | 809 | const void *callout_info, |
810 | size_t callout_len); | ||
808 | 811 | ||
809 | or: | 812 | or: |
810 | 813 | ||
811 | struct key *request_key_async_with_auxdata(const struct key_type *type, | 814 | struct key *request_key_async_with_auxdata(const struct key_type *type, |
812 | const char *description, | 815 | const char *description, |
813 | const char *callout_string, | 816 | const char *callout_info, |
817 | size_t callout_len, | ||
814 | void *aux); | 818 | void *aux); |
815 | 819 | ||
816 | which are asynchronous equivalents of request_key() and | 820 | which are asynchronous equivalents of request_key() and |
diff --git a/include/linux/key.h b/include/linux/key.h index a70b8a8f2005..163f864b6bd4 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -208,16 +208,19 @@ extern struct key *request_key(struct key_type *type, | |||
208 | 208 | ||
209 | extern struct key *request_key_with_auxdata(struct key_type *type, | 209 | extern struct key *request_key_with_auxdata(struct key_type *type, |
210 | const char *description, | 210 | const char *description, |
211 | const char *callout_info, | 211 | const void *callout_info, |
212 | size_t callout_len, | ||
212 | void *aux); | 213 | void *aux); |
213 | 214 | ||
214 | extern struct key *request_key_async(struct key_type *type, | 215 | extern struct key *request_key_async(struct key_type *type, |
215 | const char *description, | 216 | const char *description, |
216 | const char *callout_info); | 217 | const void *callout_info, |
218 | size_t callout_len); | ||
217 | 219 | ||
218 | extern struct key *request_key_async_with_auxdata(struct key_type *type, | 220 | extern struct key *request_key_async_with_auxdata(struct key_type *type, |
219 | const char *description, | 221 | const char *description, |
220 | const char *callout_info, | 222 | const void *callout_info, |
223 | size_t callout_len, | ||
221 | void *aux); | 224 | void *aux); |
222 | 225 | ||
223 | extern int wait_for_key_construction(struct key *key, bool intr); | 226 | extern int wait_for_key_construction(struct key *key, bool intr); |
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); |