1 /* request_key.c: request a key from userspace 2 * 3 * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * See Documentation/keys-request-key.txt 12 */ 13 14 #include <linux/module.h> 15 #include <linux/sched.h> 16 #include <linux/kmod.h> 17 #include <linux/err.h> 18 #include <linux/keyctl.h> 19 #include "internal.h" 20 21 struct key_construction { 22 struct list_head link; /* link in construction queue */ 23 struct key *key; /* key being constructed */ 24 }; 25 26 /* when waiting for someone else's keys, you get added to this */ 27 DECLARE_WAIT_QUEUE_HEAD(request_key_conswq); 28 29 /*****************************************************************************/ 30 /* 31 * request userspace finish the construction of a key 32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" 33 */ 34 static int call_sbin_request_key(struct key *key, 35 struct key *authkey, 36 const char *op, 37 void *aux) 38 { 39 struct task_struct *tsk = current; 40 key_serial_t prkey, sskey; 41 struct key *keyring; 42 char *argv[9], *envp[3], uid_str[12], gid_str[12]; 43 char key_str[12], keyring_str[3][12]; 44 char desc[20]; 45 int ret, i; 46 47 kenter("{%d},{%d},%s", key->serial, authkey->serial, op); 48 49 /* allocate a new session keyring */ 50 sprintf(desc, "_req.%u", key->serial); 51 52 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, current, 53 KEY_ALLOC_QUOTA_OVERRUN, NULL); 54 if (IS_ERR(keyring)) { 55 ret = PTR_ERR(keyring); 56 goto error_alloc; 57 } 58 59 /* attach the auth key to the session keyring */ 60 ret = __key_link(keyring, authkey); 61 if (ret < 0) 62 goto error_link; 63 64 /* record the UID and GID */ 65 sprintf(uid_str, "%d", current->fsuid); 66 sprintf(gid_str, "%d", current->fsgid); 67 68 /* we say which key is under construction */ 69 sprintf(key_str, "%d", key->serial); 70 71 /* we specify the process's default keyrings */ 72 sprintf(keyring_str[0], "%d", 73 tsk->thread_keyring ? tsk->thread_keyring->serial : 0); 74 75 prkey = 0; 76 if (tsk->signal->process_keyring) 77 prkey = tsk->signal->process_keyring->serial; 78 79 sprintf(keyring_str[1], "%d", prkey); 80 81 if (tsk->signal->session_keyring) { 82 rcu_read_lock(); 83 sskey = rcu_dereference(tsk->signal->session_keyring)->serial; 84 rcu_read_unlock(); 85 } 86 else { 87 sskey = tsk->user->session_keyring->serial; 88 } 89 90 sprintf(keyring_str[2], "%d", sskey); 91 92 /* set up a minimal environment */ 93 i = 0; 94 envp[i++] = "HOME=/"; 95 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 96 envp[i] = NULL; 97 98 /* set up the argument list */ 99 i = 0; 100 argv[i++] = "/sbin/request-key"; 101 argv[i++] = (char *) op; 102 argv[i++] = key_str; 103 argv[i++] = uid_str; 104 argv[i++] = gid_str; 105 argv[i++] = keyring_str[0]; 106 argv[i++] = keyring_str[1]; 107 argv[i++] = keyring_str[2]; 108 argv[i] = NULL; 109 110 /* do it */ 111 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 112 UMH_WAIT_PROC); 113 114 error_link: 115 key_put(keyring); 116 117 error_alloc: 118 kleave(" = %d", ret); 119 return ret; 120 121 } /* end call_sbin_request_key() */ 122 123 /*****************************************************************************/ 124 /* 125 * call out to userspace for the key 126 * - called with the construction sem held, but the sem is dropped here 127 * - we ignore program failure and go on key status instead 128 */ 129 static struct key *__request_key_construction(struct key_type *type, 130 const char *description, 131 const char *callout_info, 132 void *aux, 133 unsigned long flags) 134 { 135 request_key_actor_t actor; 136 struct key_construction cons; 137 struct timespec now; 138 struct key *key, *authkey; 139 int ret, negated; 140 141 kenter("%s,%s,%s,%lx", type->name, description, callout_info, flags); 142 143 /* create a key and add it to the queue */ 144 key = key_alloc(type, description, 145 current->fsuid, current->fsgid, current, KEY_POS_ALL, 146 flags); 147 if (IS_ERR(key)) 148 goto alloc_failed; 149 150 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 151 152 cons.key = key; 153 list_add_tail(&cons.link, &key->user->consq); 154 155 /* we drop the construction sem here on behalf of the caller */ 156 up_write(&key_construction_sem); 157 158 /* allocate an authorisation key */ 159 authkey = request_key_auth_new(key, callout_info); 160 if (IS_ERR(authkey)) { 161 ret = PTR_ERR(authkey); 162 authkey = NULL; 163 goto alloc_authkey_failed; 164 } 165 166 /* make the call */ 167 actor = call_sbin_request_key; 168 if (type->request_key) 169 actor = type->request_key; 170 ret = actor(key, authkey, "create", aux); 171 if (ret < 0) 172 goto request_failed; 173 174 /* if the key wasn't instantiated, then we want to give an error */ 175 ret = -ENOKEY; 176 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 177 goto request_failed; 178 179 key_revoke(authkey); 180 key_put(authkey); 181 182 down_write(&key_construction_sem); 183 list_del(&cons.link); 184 up_write(&key_construction_sem); 185 186 /* also give an error if the key was negatively instantiated */ 187 check_not_negative: 188 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 189 key_put(key); 190 key = ERR_PTR(-ENOKEY); 191 } 192 193 out: 194 kleave(" = %p", key); 195 return key; 196 197 request_failed: 198 key_revoke(authkey); 199 key_put(authkey); 200 201 alloc_authkey_failed: 202 /* it wasn't instantiated 203 * - remove from construction queue 204 * - mark the key as dead 205 */ 206 negated = 0; 207 down_write(&key_construction_sem); 208 209 list_del(&cons.link); 210 211 /* check it didn't get instantiated between the check and the down */ 212 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 213 set_bit(KEY_FLAG_NEGATIVE, &key->flags); 214 set_bit(KEY_FLAG_INSTANTIATED, &key->flags); 215 negated = 1; 216 } 217 218 clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 219 220 up_write(&key_construction_sem); 221 222 if (!negated) 223 goto check_not_negative; /* surprisingly, the key got 224 * instantiated */ 225 226 /* set the timeout and store in the session keyring if we can */ 227 now = current_kernel_time(); 228 key->expiry = now.tv_sec + key_negative_timeout; 229 230 if (current->signal->session_keyring) { 231 struct key *keyring; 232 233 rcu_read_lock(); 234 keyring = rcu_dereference(current->signal->session_keyring); 235 atomic_inc(&keyring->usage); 236 rcu_read_unlock(); 237 238 key_link(keyring, key); 239 key_put(keyring); 240 } 241 242 key_put(key); 243 244 /* notify anyone who was waiting */ 245 wake_up_all(&request_key_conswq); 246 247 key = ERR_PTR(ret); 248 goto out; 249 250 alloc_failed: 251 up_write(&key_construction_sem); 252 goto out; 253 254 } /* end __request_key_construction() */ 255 256 /*****************************************************************************/ 257 /* 258 * call out to userspace to request the key 259 * - we check the construction queue first to see if an appropriate key is 260 * already being constructed by userspace 261 */ 262 static struct key *request_key_construction(struct key_type *type, 263 const char *description, 264 const char *callout_info, 265 void *aux, 266 struct key_user *user, 267 unsigned long flags) 268 { 269 struct key_construction *pcons; 270 struct key *key, *ckey; 271 272 DECLARE_WAITQUEUE(myself, current); 273 274 kenter("%s,%s,{%d},%s,%lx", 275 type->name, description, user->uid, callout_info, flags); 276 277 /* see if there's such a key under construction already */ 278 down_write(&key_construction_sem); 279 280 list_for_each_entry(pcons, &user->consq, link) { 281 ckey = pcons->key; 282 283 if (ckey->type != type) 284 continue; 285 286 if (type->match(ckey, description)) 287 goto found_key_under_construction; 288 } 289 290 /* see about getting userspace to construct the key */ 291 key = __request_key_construction(type, description, callout_info, aux, 292 flags); 293 error: 294 kleave(" = %p", key); 295 return key; 296 297 /* someone else has the same key under construction 298 * - we want to keep an eye on their key 299 */ 300 found_key_under_construction: 301 atomic_inc(&ckey->usage); 302 up_write(&key_construction_sem); 303 304 /* wait for the key to be completed one way or another */ 305 add_wait_queue(&request_key_conswq, &myself); 306 307 for (;;) { 308 set_current_state(TASK_INTERRUPTIBLE); 309 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags)) 310 break; 311 if (signal_pending(current)) 312 break; 313 schedule(); 314 } 315 316 set_current_state(TASK_RUNNING); 317 remove_wait_queue(&request_key_conswq, &myself); 318 319 /* we'll need to search this process's keyrings to see if the key is 320 * now there since we can't automatically assume it's also available 321 * there */ 322 key_put(ckey); 323 ckey = NULL; 324 325 key = NULL; /* request a retry */ 326 goto error; 327 328 } /* end request_key_construction() */ 329 330 /*****************************************************************************/ 331 /* 332 * link a freshly minted key to an appropriate destination keyring 333 */ 334 static void request_key_link(struct key *key, struct key *dest_keyring) 335 { 336 struct task_struct *tsk = current; 337 struct key *drop = NULL; 338 339 kenter("{%d},%p", key->serial, dest_keyring); 340 341 /* find the appropriate keyring */ 342 if (!dest_keyring) { 343 switch (tsk->jit_keyring) { 344 case KEY_REQKEY_DEFL_DEFAULT: 345 case KEY_REQKEY_DEFL_THREAD_KEYRING: 346 dest_keyring = tsk->thread_keyring; 347 if (dest_keyring) 348 break; 349 350 case KEY_REQKEY_DEFL_PROCESS_KEYRING: 351 dest_keyring = tsk->signal->process_keyring; 352 if (dest_keyring) 353 break; 354 355 case KEY_REQKEY_DEFL_SESSION_KEYRING: 356 rcu_read_lock(); 357 dest_keyring = key_get( 358 rcu_dereference(tsk->signal->session_keyring)); 359 rcu_read_unlock(); 360 drop = dest_keyring; 361 362 if (dest_keyring) 363 break; 364 365 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: 366 dest_keyring = current->user->session_keyring; 367 break; 368 369 case KEY_REQKEY_DEFL_USER_KEYRING: 370 dest_keyring = current->user->uid_keyring; 371 break; 372 373 case KEY_REQKEY_DEFL_GROUP_KEYRING: 374 default: 375 BUG(); 376 } 377 } 378 379 /* and attach the key to it */ 380 key_link(dest_keyring, key); 381 382 key_put(drop); 383 384 kleave(""); 385 386 } /* end request_key_link() */ 387 388 /*****************************************************************************/ 389 /* 390 * request a key 391 * - search the process's keyrings 392 * - check the list of keys being created or updated 393 * - call out to userspace for a key if supplementary info was provided 394 * - cache the key in an appropriate keyring 395 */ 396 struct key *request_key_and_link(struct key_type *type, 397 const char *description, 398 const char *callout_info, 399 void *aux, 400 struct key *dest_keyring, 401 unsigned long flags) 402 { 403 struct key_user *user; 404 struct key *key; 405 key_ref_t key_ref; 406 407 kenter("%s,%s,%s,%p,%p,%lx", 408 type->name, description, callout_info, aux, 409 dest_keyring, flags); 410 411 /* search all the process keyrings for a key */ 412 key_ref = search_process_keyrings(type, description, type->match, 413 current); 414 415 kdebug("search 1: %p", key_ref); 416 417 if (!IS_ERR(key_ref)) { 418 key = key_ref_to_ptr(key_ref); 419 } 420 else if (PTR_ERR(key_ref) != -EAGAIN) { 421 key = ERR_PTR(PTR_ERR(key_ref)); 422 } 423 else { 424 /* the search failed, but the keyrings were searchable, so we 425 * should consult userspace if we can */ 426 key = ERR_PTR(-ENOKEY); 427 if (!callout_info) 428 goto error; 429 430 /* - get hold of the user's construction queue */ 431 user = key_user_lookup(current->fsuid); 432 if (!user) 433 goto nomem; 434 435 for (;;) { 436 if (signal_pending(current)) 437 goto interrupted; 438 439 /* ask userspace (returns NULL if it waited on a key 440 * being constructed) */ 441 key = request_key_construction(type, description, 442 callout_info, aux, 443 user, flags); 444 if (key) 445 break; 446 447 /* someone else made the key we want, so we need to 448 * search again as it might now be available to us */ 449 key_ref = search_process_keyrings(type, description, 450 type->match, 451 current); 452 453 kdebug("search 2: %p", key_ref); 454 455 if (!IS_ERR(key_ref)) { 456 key = key_ref_to_ptr(key_ref); 457 break; 458 } 459 460 if (PTR_ERR(key_ref) != -EAGAIN) { 461 key = ERR_PTR(PTR_ERR(key_ref)); 462 break; 463 } 464 } 465 466 key_user_put(user); 467 468 /* link the new key into the appropriate keyring */ 469 if (!IS_ERR(key)) 470 request_key_link(key, dest_keyring); 471 } 472 473 error: 474 kleave(" = %p", key); 475 return key; 476 477 nomem: 478 key = ERR_PTR(-ENOMEM); 479 goto error; 480 481 interrupted: 482 key_user_put(user); 483 key = ERR_PTR(-EINTR); 484 goto error; 485 486 } /* end request_key_and_link() */ 487 488 /*****************************************************************************/ 489 /* 490 * request a key 491 * - search the process's keyrings 492 * - check the list of keys being created or updated 493 * - call out to userspace for a key if supplementary info was provided 494 */ 495 struct key *request_key(struct key_type *type, 496 const char *description, 497 const char *callout_info) 498 { 499 return request_key_and_link(type, description, callout_info, NULL, 500 NULL, KEY_ALLOC_IN_QUOTA); 501 502 } /* end request_key() */ 503 504 EXPORT_SYMBOL(request_key); 505 506 /*****************************************************************************/ 507 /* 508 * request a key with auxiliary data for the upcaller 509 * - search the process's keyrings 510 * - check the list of keys being created or updated 511 * - call out to userspace for a key if supplementary info was provided 512 */ 513 struct key *request_key_with_auxdata(struct key_type *type, 514 const char *description, 515 const char *callout_info, 516 void *aux) 517 { 518 return request_key_and_link(type, description, callout_info, aux, 519 NULL, KEY_ALLOC_IN_QUOTA); 520 521 } /* end request_key_with_auxdata() */ 522 523 EXPORT_SYMBOL(request_key_with_auxdata); 524