aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-04-29 04:01:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:16 -0400
commit4a38e122e2cc6294779021ff4ccc784a3997059e (patch)
tree84b401b44e0550b04f831d98a91eacfd7cffb51d
parentdceba9944181b1fd5993417b5c8fa0e3dda38f8d (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.txt11
-rw-r--r--Documentation/keys.txt14
-rw-r--r--include/linux/key.h9
-rw-r--r--security/keys/internal.h9
-rw-r--r--security/keys/keyctl.c7
-rw-r--r--security/keys/request_key.c49
-rw-r--r--security/keys/request_key_auth.c12
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
16or: 16or:
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
23or: 24or:
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
29or: 31or:
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
36Or by userspace invoking the request_key system call: 39Or 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
209extern struct key *request_key_with_auxdata(struct key_type *type, 209extern 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
214extern struct key *request_key_async(struct key_type *type, 215extern 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
218extern struct key *request_key_async_with_auxdata(struct key_type *type, 220extern 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
223extern int wait_for_key_construction(struct key *key, bool intr); 226extern 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
110extern struct key *request_key_and_link(struct key_type *type, 110extern 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,
120struct request_key_auth { 121struct 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
127extern struct key_type key_type_request_key_auth; 129extern struct key_type key_type_request_key_auth;
128extern struct key *request_key_auth_new(struct key *target, 130extern 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
131extern struct key *key_get_instantiation_authkey(key_serial_t target_id); 134extern 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 */
164static int construct_key(struct key *key, const char *callout_info, void *aux) 164static 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:
331static struct key *construct_key_and_link(struct key_type *type, 332static 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 */
371struct key *request_key_and_link(struct key_type *type, 373struct 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
404error: 408error:
@@ -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 */
459struct key *request_key_with_auxdata(struct key_type *type, 466struct 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 */
486struct key *request_key_async(struct key_type *type, 494struct 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}
493EXPORT_SYMBOL(request_key_async); 503EXPORT_SYMBOL(request_key_async);
494 504
@@ -500,10 +510,11 @@ EXPORT_SYMBOL(request_key_async);
500 */ 510 */
501struct key *request_key_async_with_auxdata(struct key_type *type, 511struct 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}
509EXPORT_SYMBOL(request_key_async_with_auxdata); 520EXPORT_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 */
140struct key *request_key_auth_new(struct key *target, const char *callout_info) 140struct 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);