aboutsummaryrefslogtreecommitdiffstats
path: root/security
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 /security
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>
Diffstat (limited to 'security')
-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
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
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);