request_key.c (16feef4340172b7dbb9cba60850e78fa6388adf1) | request_key.c (4bdf0bc300314141e5475e145acb8b5ad846f00d) |
---|---|
1/* Request a key from userspace 2 * 3 * Copyright (C) 2004-2007 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 --- 331 unchanged lines hidden (view full) --- 340 341/* 342 * Allocate a new key in under-construction state and attempt to link it in to 343 * the requested keyring. 344 * 345 * May return a key that's already under construction instead if there was a 346 * race between two thread calling request_key(). 347 */ | 1/* Request a key from userspace 2 * 3 * Copyright (C) 2004-2007 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 --- 331 unchanged lines hidden (view full) --- 340 341/* 342 * Allocate a new key in under-construction state and attempt to link it in to 343 * the requested keyring. 344 * 345 * May return a key that's already under construction instead if there was a 346 * race between two thread calling request_key(). 347 */ |
348static int construct_alloc_key(struct key_type *type, 349 const char *description, | 348static int construct_alloc_key(struct keyring_search_context *ctx, |
350 struct key *dest_keyring, 351 unsigned long flags, 352 struct key_user *user, 353 struct key **_key) 354{ | 349 struct key *dest_keyring, 350 unsigned long flags, 351 struct key_user *user, 352 struct key **_key) 353{ |
355 const struct keyring_index_key index_key = { 356 .type = type, 357 .description = description, 358 .desc_len = strlen(description), 359 }; 360 const struct cred *cred = current_cred(); | |
361 unsigned long prealloc; 362 struct key *key; 363 key_perm_t perm; 364 key_ref_t key_ref; 365 int ret; 366 | 354 unsigned long prealloc; 355 struct key *key; 356 key_perm_t perm; 357 key_ref_t key_ref; 358 int ret; 359 |
367 kenter("%s,%s,,,", type->name, description); | 360 kenter("%s,%s,,,", 361 ctx->index_key.type->name, ctx->index_key.description); |
368 369 *_key = NULL; 370 mutex_lock(&user->cons_lock); 371 372 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; 373 perm |= KEY_USR_VIEW; | 362 363 *_key = NULL; 364 mutex_lock(&user->cons_lock); 365 366 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; 367 perm |= KEY_USR_VIEW; |
374 if (type->read) | 368 if (ctx->index_key.type->read) |
375 perm |= KEY_POS_READ; | 369 perm |= KEY_POS_READ; |
376 if (type == &key_type_keyring || type->update) | 370 if (ctx->index_key.type == &key_type_keyring || 371 ctx->index_key.type->update) |
377 perm |= KEY_POS_WRITE; 378 | 372 perm |= KEY_POS_WRITE; 373 |
379 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred, | 374 key = key_alloc(ctx->index_key.type, ctx->index_key.description, 375 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred, |
380 perm, flags); 381 if (IS_ERR(key)) 382 goto alloc_failed; 383 384 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 385 386 if (dest_keyring) { | 376 perm, flags); 377 if (IS_ERR(key)) 378 goto alloc_failed; 379 380 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 381 382 if (dest_keyring) { |
387 ret = __key_link_begin(dest_keyring, &index_key, &prealloc); | 383 ret = __key_link_begin(dest_keyring, &ctx->index_key, &prealloc); |
388 if (ret < 0) 389 goto link_prealloc_failed; 390 } 391 392 /* attach the key to the destination keyring under lock, but we do need 393 * to do another check just in case someone beat us to it whilst we 394 * waited for locks */ 395 mutex_lock(&key_construction_mutex); 396 | 384 if (ret < 0) 385 goto link_prealloc_failed; 386 } 387 388 /* attach the key to the destination keyring under lock, but we do need 389 * to do another check just in case someone beat us to it whilst we 390 * waited for locks */ 391 mutex_lock(&key_construction_mutex); 392 |
397 key_ref = search_process_keyrings(type, description, type->match, 398 false, cred); | 393 key_ref = search_process_keyrings(ctx); |
399 if (!IS_ERR(key_ref)) 400 goto key_already_present; 401 402 if (dest_keyring) 403 __key_link(dest_keyring, key, &prealloc); 404 405 mutex_unlock(&key_construction_mutex); 406 if (dest_keyring) | 394 if (!IS_ERR(key_ref)) 395 goto key_already_present; 396 397 if (dest_keyring) 398 __key_link(dest_keyring, key, &prealloc); 399 400 mutex_unlock(&key_construction_mutex); 401 if (dest_keyring) |
407 __key_link_end(dest_keyring, &index_key, prealloc); | 402 __key_link_end(dest_keyring, &ctx->index_key, prealloc); |
408 mutex_unlock(&user->cons_lock); 409 *_key = key; 410 kleave(" = 0 [%d]", key_serial(key)); 411 return 0; 412 413 /* the key is now present - we tell the caller that we found it by 414 * returning -EINPROGRESS */ 415key_already_present: 416 key_put(key); 417 mutex_unlock(&key_construction_mutex); 418 key = key_ref_to_ptr(key_ref); 419 if (dest_keyring) { 420 ret = __key_link_check_live_key(dest_keyring, key); 421 if (ret == 0) 422 __key_link(dest_keyring, key, &prealloc); | 403 mutex_unlock(&user->cons_lock); 404 *_key = key; 405 kleave(" = 0 [%d]", key_serial(key)); 406 return 0; 407 408 /* the key is now present - we tell the caller that we found it by 409 * returning -EINPROGRESS */ 410key_already_present: 411 key_put(key); 412 mutex_unlock(&key_construction_mutex); 413 key = key_ref_to_ptr(key_ref); 414 if (dest_keyring) { 415 ret = __key_link_check_live_key(dest_keyring, key); 416 if (ret == 0) 417 __key_link(dest_keyring, key, &prealloc); |
423 __key_link_end(dest_keyring, &index_key, prealloc); | 418 __key_link_end(dest_keyring, &ctx->index_key, prealloc); |
424 if (ret < 0) 425 goto link_check_failed; 426 } 427 mutex_unlock(&user->cons_lock); 428 *_key = key; 429 kleave(" = -EINPROGRESS [%d]", key_serial(key)); 430 return -EINPROGRESS; 431 --- 12 unchanged lines hidden (view full) --- 444 mutex_unlock(&user->cons_lock); 445 kleave(" = %ld", PTR_ERR(key)); 446 return PTR_ERR(key); 447} 448 449/* 450 * Commence key construction. 451 */ | 419 if (ret < 0) 420 goto link_check_failed; 421 } 422 mutex_unlock(&user->cons_lock); 423 *_key = key; 424 kleave(" = -EINPROGRESS [%d]", key_serial(key)); 425 return -EINPROGRESS; 426 --- 12 unchanged lines hidden (view full) --- 439 mutex_unlock(&user->cons_lock); 440 kleave(" = %ld", PTR_ERR(key)); 441 return PTR_ERR(key); 442} 443 444/* 445 * Commence key construction. 446 */ |
452static struct key *construct_key_and_link(struct key_type *type, 453 const char *description, | 447static struct key *construct_key_and_link(struct keyring_search_context *ctx, |
454 const char *callout_info, 455 size_t callout_len, 456 void *aux, 457 struct key *dest_keyring, 458 unsigned long flags) 459{ 460 struct key_user *user; 461 struct key *key; 462 int ret; 463 464 kenter(""); 465 466 user = key_user_lookup(current_fsuid()); 467 if (!user) 468 return ERR_PTR(-ENOMEM); 469 470 construct_get_dest_keyring(&dest_keyring); 471 | 448 const char *callout_info, 449 size_t callout_len, 450 void *aux, 451 struct key *dest_keyring, 452 unsigned long flags) 453{ 454 struct key_user *user; 455 struct key *key; 456 int ret; 457 458 kenter(""); 459 460 user = key_user_lookup(current_fsuid()); 461 if (!user) 462 return ERR_PTR(-ENOMEM); 463 464 construct_get_dest_keyring(&dest_keyring); 465 |
472 ret = construct_alloc_key(type, description, dest_keyring, flags, user, 473 &key); | 466 ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key); |
474 key_user_put(user); 475 476 if (ret == 0) { 477 ret = construct_key(key, callout_info, callout_len, aux, 478 dest_keyring); 479 if (ret < 0) { 480 kdebug("cons failed"); 481 goto construction_failed; --- 47 unchanged lines hidden (view full) --- 529struct key *request_key_and_link(struct key_type *type, 530 const char *description, 531 const void *callout_info, 532 size_t callout_len, 533 void *aux, 534 struct key *dest_keyring, 535 unsigned long flags) 536{ | 467 key_user_put(user); 468 469 if (ret == 0) { 470 ret = construct_key(key, callout_info, callout_len, aux, 471 dest_keyring); 472 if (ret < 0) { 473 kdebug("cons failed"); 474 goto construction_failed; --- 47 unchanged lines hidden (view full) --- 522struct key *request_key_and_link(struct key_type *type, 523 const char *description, 524 const void *callout_info, 525 size_t callout_len, 526 void *aux, 527 struct key *dest_keyring, 528 unsigned long flags) 529{ |
537 const struct cred *cred = current_cred(); | 530 struct keyring_search_context ctx = { 531 .index_key.type = type, 532 .index_key.description = description, 533 .cred = current_cred(), 534 .match = type->match, 535 .match_data = description, 536 .flags = KEYRING_SEARCH_LOOKUP_DIRECT, 537 }; |
538 struct key *key; 539 key_ref_t key_ref; 540 int ret; 541 542 kenter("%s,%s,%p,%zu,%p,%p,%lx", | 538 struct key *key; 539 key_ref_t key_ref; 540 int ret; 541 542 kenter("%s,%s,%p,%zu,%p,%p,%lx", |
543 type->name, description, callout_info, callout_len, aux, 544 dest_keyring, flags); | 543 ctx.index_key.type->name, ctx.index_key.description, 544 callout_info, callout_len, aux, dest_keyring, flags); |
545 546 /* search all the process keyrings for a key */ | 545 546 /* search all the process keyrings for a key */ |
547 key_ref = search_process_keyrings(type, description, type->match, 548 false, cred); | 547 key_ref = search_process_keyrings(&ctx); |
549 550 if (!IS_ERR(key_ref)) { 551 key = key_ref_to_ptr(key_ref); 552 if (dest_keyring) { 553 construct_get_dest_keyring(&dest_keyring); 554 ret = key_link(dest_keyring, key); 555 key_put(dest_keyring); 556 if (ret < 0) { --- 6 unchanged lines hidden (view full) --- 563 key = ERR_CAST(key_ref); 564 } else { 565 /* the search failed, but the keyrings were searchable, so we 566 * should consult userspace if we can */ 567 key = ERR_PTR(-ENOKEY); 568 if (!callout_info) 569 goto error; 570 | 548 549 if (!IS_ERR(key_ref)) { 550 key = key_ref_to_ptr(key_ref); 551 if (dest_keyring) { 552 construct_get_dest_keyring(&dest_keyring); 553 ret = key_link(dest_keyring, key); 554 key_put(dest_keyring); 555 if (ret < 0) { --- 6 unchanged lines hidden (view full) --- 562 key = ERR_CAST(key_ref); 563 } else { 564 /* the search failed, but the keyrings were searchable, so we 565 * should consult userspace if we can */ 566 key = ERR_PTR(-ENOKEY); 567 if (!callout_info) 568 goto error; 569 |
571 key = construct_key_and_link(type, description, callout_info, 572 callout_len, aux, dest_keyring, 573 flags); | 570 key = construct_key_and_link(&ctx, callout_info, callout_len, 571 aux, dest_keyring, flags); |
574 } 575 576error: 577 kleave(" = %p", key); 578 return key; 579} 580 581/** --- 147 unchanged lines hidden --- | 572 } 573 574error: 575 kleave(" = %p", key); 576 return key; 577} 578 579/** --- 147 unchanged lines hidden --- |