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