示例#1
0
/*
 * instantiate a request-key authorisation record
 */
static int request_key_auth_instantiate(struct key *key,
					const void *data,
					size_t datalen)
{
	struct request_key_auth *rka, *irka;
	struct key *instkey;
	int ret;

	ret = -ENOMEM;
	rka = kmalloc(sizeof(*rka), GFP_KERNEL);
	if (rka) {
		/* see if the calling process is already servicing the key
		 * request of another process */
		instkey = key_get_instantiation_authkey(0);
		if (!IS_ERR(instkey)) {
			/* it is - use that instantiation context here too */
			irka = instkey->payload.data;
			rka->context = irka->context;
			rka->pid = irka->pid;
			key_put(instkey);
		}
		else {
			/* it isn't - use this process as the context */
			rka->context = current;
			rka->pid = current->pid;
		}

		rka->target_key = key_get((struct key *) data);
		key->payload.data = rka;
		ret = 0;
	}

	return ret;

} /* end request_key_auth_instantiate() */
示例#2
0
/*
 * negatively instantiate the key with the given timeout (in seconds), and, if
 * one is given, link the key into the keyring
 */
long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
{
	struct request_key_auth *rka;
	struct key *instkey;
	key_ref_t keyring_ref;
	long ret;

	/* find the instantiation authorisation key */
	instkey = key_get_instantiation_authkey(id);
	if (IS_ERR(instkey)) {
		ret = PTR_ERR(instkey);
		goto error;
	}

	rka = instkey->payload.data;

	/* find the destination keyring if present (which must also be
	 * writable) */
	keyring_ref = NULL;
	if (ringid) {
		keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
		if (IS_ERR(keyring_ref)) {
			ret = PTR_ERR(keyring_ref);
			goto error2;
		}
	}

	/* instantiate the key and link it into a keyring */
	ret = key_negate_and_link(rka->target_key, timeout,
				  key_ref_to_ptr(keyring_ref), instkey);

	key_ref_put(keyring_ref);
 error2:
	key_put(instkey);
 error:
	return ret;

} /* end keyctl_negate_key() */
示例#3
0
/*
 * instantiate the key with the specified payload, and, if one is given, link
 * the key into the keyring
 */
long keyctl_instantiate_key(key_serial_t id,
			    const void __user *_payload,
			    size_t plen,
			    key_serial_t ringid)
{
	struct request_key_auth *rka;
	struct key *instkey;
	key_ref_t keyring_ref;
	void *payload;
	long ret;

	ret = -EINVAL;
	if (plen > 32767)
		goto error;

	/* pull the payload in if one was supplied */
	payload = NULL;

	if (_payload) {
		ret = -ENOMEM;
		payload = kmalloc(plen, GFP_KERNEL);
		if (!payload)
			goto error;

		ret = -EFAULT;
		if (copy_from_user(payload, _payload, plen) != 0)
			goto error2;
	}

	/* find the instantiation authorisation key */
	instkey = key_get_instantiation_authkey(id);
	if (IS_ERR(instkey)) {
		ret = PTR_ERR(instkey);
		goto error2;
	}

	rka = instkey->payload.data;

	/* find the destination keyring amongst those belonging to the
	 * requesting task */
	keyring_ref = NULL;
	if (ringid) {
		keyring_ref = lookup_user_key(rka->context, ringid, 1, 0,
					      KEY_WRITE);
		if (IS_ERR(keyring_ref)) {
			ret = PTR_ERR(keyring_ref);
			goto error3;
		}
	}

	/* instantiate the key and link it into a keyring */
	ret = key_instantiate_and_link(rka->target_key, payload, plen,
				       key_ref_to_ptr(keyring_ref), instkey);

	key_ref_put(keyring_ref);
 error3:
	key_put(instkey);
 error2:
	kfree(payload);
 error:
	return ret;

} /* end keyctl_instantiate_key() */
示例#4
0
/*
 * describe a user key
 * - the key must have view permission
 * - if there's a buffer, we place up to buflen bytes of data into it
 * - unless there's an error, we return the amount of description available,
 *   irrespective of how much we may have copied
 * - the description is formatted thus:
 *	type;uid;gid;perm;description<NUL>
 * - implements keyctl(KEYCTL_DESCRIBE)
 */
long keyctl_describe_key(key_serial_t keyid,
			 char __user *buffer,
			 size_t buflen)
{
	struct key *key, *instkey;
	key_ref_t key_ref;
	char *tmpbuf;
	long ret;

	key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
	if (IS_ERR(key_ref)) {
		/* viewing a key under construction is permitted if we have the
		 * authorisation token handy */
		if (PTR_ERR(key_ref) == -EACCES) {
			instkey = key_get_instantiation_authkey(keyid);
			if (!IS_ERR(instkey)) {
				key_put(instkey);
				key_ref = lookup_user_key(NULL, keyid,
							  0, 1, 0);
				if (!IS_ERR(key_ref))
					goto okay;
			}
		}

		ret = PTR_ERR(key_ref);
		goto error;
	}

okay:
	/* calculate how much description we're going to return */
	ret = -ENOMEM;
	tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!tmpbuf)
		goto error2;

	key = key_ref_to_ptr(key_ref);

	ret = snprintf(tmpbuf, PAGE_SIZE - 1,
		       "%s;%d;%d;%08x;%s",
		       key_ref_to_ptr(key_ref)->type->name,
		       key_ref_to_ptr(key_ref)->uid,
		       key_ref_to_ptr(key_ref)->gid,
		       key_ref_to_ptr(key_ref)->perm,
		       key_ref_to_ptr(key_ref)->description ?
		       key_ref_to_ptr(key_ref)->description : ""
		       );

	/* include a NUL char at the end of the data */
	if (ret > PAGE_SIZE - 1)
		ret = PAGE_SIZE - 1;
	tmpbuf[ret] = 0;
	ret++;

	/* consider returning the data */
	if (buffer && buflen > 0) {
		if (buflen > ret)
			buflen = ret;

		if (copy_to_user(buffer, tmpbuf, buflen) != 0)
			ret = -EFAULT;
	}

	kfree(tmpbuf);
 error2:
	key_ref_put(key_ref);
 error:
	return ret;

} /* end keyctl_describe_key() */