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