security/keys/keyctl_pkey.c

Source file repositories/reference/linux-study-clean/security/keys/keyctl_pkey.c

File Facts

System
Linux kernel
Corpus path
security/keys/keyctl_pkey.c
Extension
.c
Size
7397 bytes
Lines
336
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (token) {
		case Opt_enc:
			params->encoding = q;
			break;

		case Opt_hash:
			params->hash_algo = q;
			break;

		default:
			return -EINVAL;
		}
	}

	return 0;
}

/*
 * Interpret parameters.  Callers must always call the free function
 * on params, even if an error is returned.
 */
static int keyctl_pkey_params_get(key_serial_t id,
				  const char __user *_info,
				  struct kernel_pkey_params *params)
{
	key_ref_t key_ref;
	void *p;
	int ret;

	memset(params, 0, sizeof(*params));
	params->encoding = "raw";

	p = strndup_user(_info, PAGE_SIZE);
	if (IS_ERR(p))
		return PTR_ERR(p);
	params->info = p;

	ret = keyctl_pkey_params_parse(params);
	if (ret < 0)
		return ret;

	key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
	if (IS_ERR(key_ref))
		return PTR_ERR(key_ref);
	params->key = key_ref_to_ptr(key_ref);

	if (!params->key->type->asym_query)
		return -EOPNOTSUPP;

	return 0;
}

/*
 * Get parameters from userspace.  Callers must always call the free function
 * on params, even if an error is returned.
 */
static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_params,
				    const char __user *_info,
				    int op,
				    struct kernel_pkey_params *params)
{
	struct keyctl_pkey_params uparams;
	struct kernel_pkey_query info;
	int ret;

	memset(params, 0, sizeof(*params));
	params->encoding = "raw";

	if (copy_from_user(&uparams, _params, sizeof(uparams)) != 0)
		return -EFAULT;

	ret = keyctl_pkey_params_get(uparams.key_id, _info, params);
	if (ret < 0)
		return ret;

	ret = params->key->type->asym_query(params, &info);
	if (ret < 0)
		return ret;

	switch (op) {
	case KEYCTL_PKEY_ENCRYPT:
		if (uparams.in_len  > info.max_dec_size ||
		    uparams.out_len > info.max_enc_size)
			return -EINVAL;

		params->out_len = info.max_enc_size;
		break;
	case KEYCTL_PKEY_DECRYPT:
		if (uparams.in_len  > info.max_enc_size ||
		    uparams.out_len > info.max_dec_size)

Annotation

Implementation Notes