request_key.c 15.8 KB
Newer Older
1
/* Request a key from userspace
L
Linus Torvalds 已提交
2
 *
3
 * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
L
Linus Torvalds 已提交
4 5 6 7 8 9
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
10 11
 *
 * See Documentation/keys-request-key.txt
L
Linus Torvalds 已提交
12 13 14 15 16 17
 */

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kmod.h>
#include <linux/err.h>
18
#include <linux/keyctl.h>
19
#include <linux/slab.h>
L
Linus Torvalds 已提交
20 21
#include "internal.h"

D
David Howells 已提交
22 23
#define key_negative_timeout	60	/* default timeout on a negative key's existence */

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
/*
 * wait_on_bit() sleep function for uninterruptible waiting
 */
static int key_wait_bit(void *flags)
{
	schedule();
	return 0;
}

/*
 * wait_on_bit() sleep function for interruptible waiting
 */
static int key_wait_bit_intr(void *flags)
{
	schedule();
	return signal_pending(current) ? -ERESTARTSYS : 0;
}

/*
 * call to complete the construction of a key
 */
void complete_request_key(struct key_construction *cons, int error)
{
	kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
L
Linus Torvalds 已提交
48

49 50 51 52 53 54 55 56 57 58 59
	if (error < 0)
		key_negate_and_link(cons->key, key_negative_timeout, NULL,
				    cons->authkey);
	else
		key_revoke(cons->authkey);

	key_put(cons->key);
	key_put(cons->authkey);
	kfree(cons);
}
EXPORT_SYMBOL(complete_request_key);
L
Linus Torvalds 已提交
60

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
static int umh_keys_init(struct subprocess_info *info)
{
	struct cred *cred = (struct cred*)current_cred();
	struct key *keyring = info->data;
	/*
	 * This is called in context of freshly forked kthread before
	 * kernel_execve(), we can just change our ->session_keyring.
	 */
	return install_session_keyring_to_cred(cred, keyring);
}

static void umh_keys_cleanup(struct subprocess_info *info)
{
	struct key *keyring = info->data;
	key_put(keyring);
}

static int call_usermodehelper_keys(char *path, char **argv, char **envp,
			 struct key *session_keyring, enum umh_wait wait)
{
	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
	struct subprocess_info *info =
		call_usermodehelper_setup(path, argv, envp, gfp_mask);

	if (!info)
		return -ENOMEM;

	call_usermodehelper_setfns(info, umh_keys_init, umh_keys_cleanup,
					key_get(session_keyring));
	return call_usermodehelper_exec(info, wait);
}

L
Linus Torvalds 已提交
93 94
/*
 * request userspace finish the construction of a key
95
 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
L
Linus Torvalds 已提交
96
 */
97
static int call_sbin_request_key(struct key_construction *cons,
98 99
				 const char *op,
				 void *aux)
L
Linus Torvalds 已提交
100
{
101
	const struct cred *cred = current_cred();
L
Linus Torvalds 已提交
102
	key_serial_t prkey, sskey;
D
David Howells 已提交
103 104
	struct key *key = cons->key, *authkey = cons->authkey, *keyring,
		*session;
105
	char *argv[9], *envp[3], uid_str[12], gid_str[12];
L
Linus Torvalds 已提交
106
	char key_str[12], keyring_str[3][12];
107
	char desc[20];
108 109
	int ret, i;

110
	kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
111

112 113 114 115
	ret = install_user_keyrings();
	if (ret < 0)
		goto error_alloc;

116 117 118
	/* allocate a new session keyring */
	sprintf(desc, "_req.%u", key->serial);

D
David Howells 已提交
119 120
	cred = get_current_cred();
	keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
121
				KEY_ALLOC_QUOTA_OVERRUN, NULL);
D
David Howells 已提交
122
	put_cred(cred);
123 124 125
	if (IS_ERR(keyring)) {
		ret = PTR_ERR(keyring);
		goto error_alloc;
126
	}
L
Linus Torvalds 已提交
127

128
	/* attach the auth key to the session keyring */
129
	ret = key_link(keyring, authkey);
130 131 132
	if (ret < 0)
		goto error_link;

L
Linus Torvalds 已提交
133
	/* record the UID and GID */
134 135
	sprintf(uid_str, "%d", cred->fsuid);
	sprintf(gid_str, "%d", cred->fsgid);
L
Linus Torvalds 已提交
136 137 138 139 140 141

	/* we say which key is under construction */
	sprintf(key_str, "%d", key->serial);

	/* we specify the process's default keyrings */
	sprintf(keyring_str[0], "%d",
D
David Howells 已提交
142
		cred->thread_keyring ? cred->thread_keyring->serial : 0);
L
Linus Torvalds 已提交
143 144

	prkey = 0;
145 146
	if (cred->tgcred->process_keyring)
		prkey = cred->tgcred->process_keyring->serial;
147
	sprintf(keyring_str[1], "%d", prkey);
L
Linus Torvalds 已提交
148

D
David Howells 已提交
149 150 151 152 153 154
	rcu_read_lock();
	session = rcu_dereference(cred->tgcred->session_keyring);
	if (!session)
		session = cred->user->session_keyring;
	sskey = session->serial;
	rcu_read_unlock();
L
Linus Torvalds 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176

	sprintf(keyring_str[2], "%d", sskey);

	/* set up a minimal environment */
	i = 0;
	envp[i++] = "HOME=/";
	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
	envp[i] = NULL;

	/* set up the argument list */
	i = 0;
	argv[i++] = "/sbin/request-key";
	argv[i++] = (char *) op;
	argv[i++] = key_str;
	argv[i++] = uid_str;
	argv[i++] = gid_str;
	argv[i++] = keyring_str[0];
	argv[i++] = keyring_str[1];
	argv[i++] = keyring_str[2];
	argv[i] = NULL;

	/* do it */
177 178
	ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
				       UMH_WAIT_PROC);
179 180 181 182 183 184 185 186 187 188 189
	kdebug("usermode -> 0x%x", ret);
	if (ret >= 0) {
		/* ret is the exit/wait code */
		if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
		    key_validate(key) < 0)
			ret = -ENOKEY;
		else
			/* ignore any errors from userspace if the key was
			 * instantiated */
			ret = 0;
	}
190

191 192
error_link:
	key_put(keyring);
193

194
error_alloc:
195
	complete_request_key(cons, ret);
D
David Howells 已提交
196
	kleave(" = %d", ret);
197
	return ret;
198
}
L
Linus Torvalds 已提交
199 200

/*
201
 * call out to userspace for key construction
L
Linus Torvalds 已提交
202 203
 * - we ignore program failure and go on key status instead
 */
204
static int construct_key(struct key *key, const void *callout_info,
205 206
			 size_t callout_len, void *aux,
			 struct key *dest_keyring)
L
Linus Torvalds 已提交
207
{
208
	struct key_construction *cons;
209
	request_key_actor_t actor;
210 211
	struct key *authkey;
	int ret;
L
Linus Torvalds 已提交
212

213
	kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux);
214

215 216 217
	cons = kmalloc(sizeof(*cons), GFP_KERNEL);
	if (!cons)
		return -ENOMEM;
L
Linus Torvalds 已提交
218

219
	/* allocate an authorisation key */
220 221
	authkey = request_key_auth_new(key, callout_info, callout_len,
				       dest_keyring);
222
	if (IS_ERR(authkey)) {
223
		kfree(cons);
224 225
		ret = PTR_ERR(authkey);
		authkey = NULL;
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
	} else {
		cons->authkey = key_get(authkey);
		cons->key = key_get(key);

		/* make the call */
		actor = call_sbin_request_key;
		if (key->type->request_key)
			actor = key->type->request_key;

		ret = actor(cons, "create", aux);

		/* check that the actor called complete_request_key() prior to
		 * returning an error */
		WARN_ON(ret < 0 &&
			!test_bit(KEY_FLAG_REVOKED, &authkey->flags));
		key_put(authkey);
L
Linus Torvalds 已提交
242 243
	}

244 245 246
	kleave(" = %d", ret);
	return ret;
}
L
Linus Torvalds 已提交
247

248
/*
249 250 251
 * get the appropriate destination keyring for the request
 * - we return whatever keyring we select with an extra reference upon it which
 *   the caller must release
252
 */
253
static void construct_get_dest_keyring(struct key **_dest_keyring)
254
{
255
	struct request_key_auth *rka;
256
	const struct cred *cred = current_cred();
257
	struct key *dest_keyring = *_dest_keyring, *authkey;
258

259
	kenter("%p", dest_keyring);
260 261

	/* find the appropriate keyring */
262 263 264 265 266 267
	if (dest_keyring) {
		/* the caller supplied one */
		key_get(dest_keyring);
	} else {
		/* use a default keyring; falling through the cases until we
		 * find one that we actually have */
268
		switch (cred->jit_keyring) {
269
		case KEY_REQKEY_DEFL_DEFAULT:
270
		case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
271 272
			if (cred->request_key_auth) {
				authkey = cred->request_key_auth;
273 274 275 276 277 278 279 280 281 282 283
				down_read(&authkey->sem);
				rka = authkey->payload.data;
				if (!test_bit(KEY_FLAG_REVOKED,
					      &authkey->flags))
					dest_keyring =
						key_get(rka->dest_keyring);
				up_read(&authkey->sem);
				if (dest_keyring)
					break;
			}

284
		case KEY_REQKEY_DEFL_THREAD_KEYRING:
285
			dest_keyring = key_get(cred->thread_keyring);
286 287 288 289
			if (dest_keyring)
				break;

		case KEY_REQKEY_DEFL_PROCESS_KEYRING:
290
			dest_keyring = key_get(cred->tgcred->process_keyring);
291 292 293 294 295 296
			if (dest_keyring)
				break;

		case KEY_REQKEY_DEFL_SESSION_KEYRING:
			rcu_read_lock();
			dest_keyring = key_get(
297
				rcu_dereference(cred->tgcred->session_keyring));
298 299 300 301 302 303
			rcu_read_unlock();

			if (dest_keyring)
				break;

		case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
304
			dest_keyring =
305
				key_get(cred->user->session_keyring);
306 307 308
			break;

		case KEY_REQKEY_DEFL_USER_KEYRING:
309
			dest_keyring = key_get(cred->user->uid_keyring);
310 311 312 313 314 315 316 317
			break;

		case KEY_REQKEY_DEFL_GROUP_KEYRING:
		default:
			BUG();
		}
	}

318 319 320
	*_dest_keyring = dest_keyring;
	kleave(" [dk %d]", key_serial(dest_keyring));
	return;
321
}
322

323 324 325 326 327 328 329 330 331 332 333 334
/*
 * allocate a new key in under-construction state and attempt to link it in to
 * the requested place
 * - may return a key that's already under construction instead
 */
static int construct_alloc_key(struct key_type *type,
			       const char *description,
			       struct key *dest_keyring,
			       unsigned long flags,
			       struct key_user *user,
			       struct key **_key)
{
335
	struct keyring_list *prealloc;
D
David Howells 已提交
336
	const struct cred *cred = current_cred();
337 338
	struct key *key;
	key_ref_t key_ref;
339
	int ret;
340 341 342

	kenter("%s,%s,,,", type->name, description);

343
	*_key = NULL;
344 345
	mutex_lock(&user->cons_lock);

D
David Howells 已提交
346 347
	key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
			KEY_POS_ALL, flags);
348 349 350 351 352
	if (IS_ERR(key))
		goto alloc_failed;

	set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);

353 354 355 356 357 358
	if (dest_keyring) {
		ret = __key_link_begin(dest_keyring, type, description,
				       &prealloc);
		if (ret < 0)
			goto link_prealloc_failed;
	}
359 360 361 362 363 364

	/* attach the key to the destination keyring under lock, but we do need
	 * to do another check just in case someone beat us to it whilst we
	 * waited for locks */
	mutex_lock(&key_construction_mutex);

D
David Howells 已提交
365
	key_ref = search_process_keyrings(type, description, type->match, cred);
366 367 368
	if (!IS_ERR(key_ref))
		goto key_already_present;

369
	if (dest_keyring)
370
		__key_link(dest_keyring, key, &prealloc);
371 372

	mutex_unlock(&key_construction_mutex);
373
	if (dest_keyring)
374
		__key_link_end(dest_keyring, type, prealloc);
375 376 377 378 379
	mutex_unlock(&user->cons_lock);
	*_key = key;
	kleave(" = 0 [%d]", key_serial(key));
	return 0;

380 381
	/* the key is now present - we tell the caller that we found it by
	 * returning -EINPROGRESS  */
382
key_already_present:
383
	key_put(key);
384
	mutex_unlock(&key_construction_mutex);
385
	key = key_ref_to_ptr(key_ref);
386
	if (dest_keyring) {
387 388 389 390 391 392
		ret = __key_link_check_live_key(dest_keyring, key);
		if (ret == 0)
			__key_link(dest_keyring, key, &prealloc);
		__key_link_end(dest_keyring, type, prealloc);
		if (ret < 0)
			goto link_check_failed;
393
	}
394
	mutex_unlock(&user->cons_lock);
395
	*_key = key;
396 397 398
	kleave(" = -EINPROGRESS [%d]", key_serial(key));
	return -EINPROGRESS;

399 400 401 402 403 404 405 406 407 408 409
link_check_failed:
	mutex_unlock(&user->cons_lock);
	key_put(key);
	kleave(" = %d [linkcheck]", ret);
	return ret;

link_prealloc_failed:
	mutex_unlock(&user->cons_lock);
	kleave(" = %d [prelink]", ret);
	return ret;

410 411 412 413 414 415 416 417 418 419 420 421
alloc_failed:
	mutex_unlock(&user->cons_lock);
	kleave(" = %ld", PTR_ERR(key));
	return PTR_ERR(key);
}

/*
 * commence key construction
 */
static struct key *construct_key_and_link(struct key_type *type,
					  const char *description,
					  const char *callout_info,
422
					  size_t callout_len,
423 424 425 426 427 428 429 430
					  void *aux,
					  struct key *dest_keyring,
					  unsigned long flags)
{
	struct key_user *user;
	struct key *key;
	int ret;

D
David Howells 已提交
431 432
	kenter("");

433
	user = key_user_lookup(current_fsuid(), current_user_ns());
434 435 436
	if (!user)
		return ERR_PTR(-ENOMEM);

437 438
	construct_get_dest_keyring(&dest_keyring);

439 440 441 442 443
	ret = construct_alloc_key(type, description, dest_keyring, flags, user,
				  &key);
	key_user_put(user);

	if (ret == 0) {
444 445
		ret = construct_key(key, callout_info, callout_len, aux,
				    dest_keyring);
D
David Howells 已提交
446 447
		if (ret < 0) {
			kdebug("cons failed");
448
			goto construction_failed;
D
David Howells 已提交
449
		}
450 451 452 453
	} else if (ret == -EINPROGRESS) {
		ret = 0;
	} else {
		key = ERR_PTR(ret);
454 455
	}

456
	key_put(dest_keyring);
D
David Howells 已提交
457
	kleave(" = key %d", key_serial(key));
458 459 460 461 462
	return key;

construction_failed:
	key_negate_and_link(key, key_negative_timeout, NULL, NULL);
	key_put(key);
463
	key_put(dest_keyring);
D
David Howells 已提交
464
	kleave(" = %d", ret);
465 466
	return ERR_PTR(ret);
}
467

L
Linus Torvalds 已提交
468 469 470 471
/*
 * request a key
 * - search the process's keyrings
 * - check the list of keys being created or updated
472 473
 * - call out to userspace for a key if supplementary info was provided
 * - cache the key in an appropriate keyring
L
Linus Torvalds 已提交
474
 */
475 476
struct key *request_key_and_link(struct key_type *type,
				 const char *description,
477 478
				 const void *callout_info,
				 size_t callout_len,
479
				 void *aux,
480 481
				 struct key *dest_keyring,
				 unsigned long flags)
L
Linus Torvalds 已提交
482
{
D
David Howells 已提交
483
	const struct cred *cred = current_cred();
L
Linus Torvalds 已提交
484
	struct key *key;
485
	key_ref_t key_ref;
486
	int ret;
L
Linus Torvalds 已提交
487

488 489
	kenter("%s,%s,%p,%zu,%p,%p,%lx",
	       type->name, description, callout_info, callout_len, aux,
490
	       dest_keyring, flags);
491

L
Linus Torvalds 已提交
492
	/* search all the process keyrings for a key */
493
	key_ref = search_process_keyrings(type, description, type->match,
D
David Howells 已提交
494
					  cred);
L
Linus Torvalds 已提交
495

496 497
	if (!IS_ERR(key_ref)) {
		key = key_ref_to_ptr(key_ref);
498 499
		if (dest_keyring) {
			construct_get_dest_keyring(&dest_keyring);
500
			ret = key_link(dest_keyring, key);
501
			key_put(dest_keyring);
502 503 504 505 506
			if (ret < 0) {
				key_put(key);
				key = ERR_PTR(ret);
				goto error;
			}
507
		}
508
	} else if (PTR_ERR(key_ref) != -EAGAIN) {
509
		key = ERR_CAST(key_ref);
510
	} else  {
L
Linus Torvalds 已提交
511 512 513 514 515 516
		/* the search failed, but the keyrings were searchable, so we
		 * should consult userspace if we can */
		key = ERR_PTR(-ENOKEY);
		if (!callout_info)
			goto error;

517
		key = construct_key_and_link(type, description, callout_info,
518 519
					     callout_len, aux, dest_keyring,
					     flags);
L
Linus Torvalds 已提交
520 521
	}

522 523
error:
	kleave(" = %p", key);
L
Linus Torvalds 已提交
524
	return key;
525
}
L
Linus Torvalds 已提交
526

527 528 529 530 531 532
/*
 * wait for construction of a key to complete
 */
int wait_for_key_construction(struct key *key, bool intr)
{
	int ret;
533

534 535 536 537 538
	ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
			  intr ? key_wait_bit_intr : key_wait_bit,
			  intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
	if (ret < 0)
		return ret;
539 540
	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
		return -ENOKEY;
541 542 543
	return key_validate(key);
}
EXPORT_SYMBOL(wait_for_key_construction);
544 545 546 547 548 549

/*
 * request a key
 * - search the process's keyrings
 * - check the list of keys being created or updated
 * - call out to userspace for a key if supplementary info was provided
550
 * - waits uninterruptible for creation to complete
551 552 553 554 555
 */
struct key *request_key(struct key_type *type,
			const char *description,
			const char *callout_info)
{
556
	struct key *key;
557
	size_t callout_len = 0;
558 559
	int ret;

560 561 562 563
	if (callout_info)
		callout_len = strlen(callout_info);
	key = request_key_and_link(type, description, callout_info, callout_len,
				   NULL, NULL, KEY_ALLOC_IN_QUOTA);
564 565 566 567 568 569 570 571 572
	if (!IS_ERR(key)) {
		ret = wait_for_key_construction(key, false);
		if (ret < 0) {
			key_put(key);
			return ERR_PTR(ret);
		}
	}
	return key;
}
L
Linus Torvalds 已提交
573
EXPORT_SYMBOL(request_key);
574 575 576 577 578 579

/*
 * request a key with auxiliary data for the upcaller
 * - search the process's keyrings
 * - check the list of keys being created or updated
 * - call out to userspace for a key if supplementary info was provided
580
 * - waits uninterruptible for creation to complete
581 582 583
 */
struct key *request_key_with_auxdata(struct key_type *type,
				     const char *description,
584 585
				     const void *callout_info,
				     size_t callout_len,
586 587
				     void *aux)
{
588 589 590
	struct key *key;
	int ret;

591 592
	key = request_key_and_link(type, description, callout_info, callout_len,
				   aux, NULL, KEY_ALLOC_IN_QUOTA);
593 594 595 596 597 598 599 600 601 602
	if (!IS_ERR(key)) {
		ret = wait_for_key_construction(key, false);
		if (ret < 0) {
			key_put(key);
			return ERR_PTR(ret);
		}
	}
	return key;
}
EXPORT_SYMBOL(request_key_with_auxdata);
603

604 605 606 607 608 609 610 611
/*
 * request a key (allow async construction)
 * - search the process's keyrings
 * - check the list of keys being created or updated
 * - call out to userspace for a key if supplementary info was provided
 */
struct key *request_key_async(struct key_type *type,
			      const char *description,
612 613
			      const void *callout_info,
			      size_t callout_len)
614
{
615 616 617
	return request_key_and_link(type, description, callout_info,
				    callout_len, NULL, NULL,
				    KEY_ALLOC_IN_QUOTA);
618 619
}
EXPORT_SYMBOL(request_key_async);
620

621 622 623 624 625 626 627 628
/*
 * request a key with auxiliary data for the upcaller (allow async construction)
 * - search the process's keyrings
 * - check the list of keys being created or updated
 * - call out to userspace for a key if supplementary info was provided
 */
struct key *request_key_async_with_auxdata(struct key_type *type,
					   const char *description,
629 630
					   const void *callout_info,
					   size_t callout_len,
631 632
					   void *aux)
{
633 634
	return request_key_and_link(type, description, callout_info,
				    callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
635 636
}
EXPORT_SYMBOL(request_key_async_with_auxdata);