Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68c45c7f authored by David Howells's avatar David Howells
Browse files

Merge tag 'keys-fixes-20140916' into keys-next



Merge in keyrings fixes, at least some of which later patches depend on:

 (1) Reinstate the production of EPERM for key types beginning with '.' in
     requests from userspace.

 (2) Tidy up the cleanup of PKCS#7 message signed information blocks and fix a
     bug this made more obvious.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.coM>
parents ac60ab4b cecf5d2e
Loading
Loading
Loading
Loading
+33 −28
Original line number Diff line number Diff line
@@ -31,6 +31,18 @@ struct pkcs7_parse_context {
	unsigned	sinfo_index;
};

/*
 * Free a signed information block.
 */
static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
{
	if (sinfo) {
		mpi_free(sinfo->sig.mpi[0]);
		kfree(sinfo->sig.digest);
		kfree(sinfo);
	}
}

/**
 * pkcs7_free_message - Free a PKCS#7 message
 * @pkcs7: The PKCS#7 message to free
@@ -54,9 +66,7 @@ void pkcs7_free_message(struct pkcs7_message *pkcs7)
		while (pkcs7->signed_infos) {
			sinfo = pkcs7->signed_infos;
			pkcs7->signed_infos = sinfo->next;
			mpi_free(sinfo->sig.mpi[0]);
			kfree(sinfo->sig.digest);
			kfree(sinfo);
			pkcs7_free_signed_info(sinfo);
		}
		kfree(pkcs7);
	}
@@ -71,51 +81,46 @@ EXPORT_SYMBOL_GPL(pkcs7_free_message);
struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
{
	struct pkcs7_parse_context *ctx;
	struct pkcs7_message *msg;
	long ret;
	struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
	int ret;

	ret = -ENOMEM;
	msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
	if (!msg)
		goto error_no_sig;
	ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
	if (!ctx)
		goto error_no_ctx;
		goto out_no_ctx;
	ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
	if (!ctx->msg)
		goto out_no_msg;
	ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
	if (!ctx->sinfo)
		goto error_no_sinfo;
		goto out_no_sinfo;

	ctx->msg = msg;
	ctx->data = (unsigned long)data;
	ctx->ppcerts = &ctx->certs;
	ctx->ppsinfo = &ctx->msg->signed_infos;

	/* Attempt to decode the signature */
	ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
	if (ret < 0)
		goto error_decode;
	if (ret < 0) {
		msg = ERR_PTR(ret);
		goto out;
	}

	msg = ctx->msg;
	ctx->msg = NULL;

out:
	while (ctx->certs) {
		struct x509_certificate *cert = ctx->certs;
		ctx->certs = cert->next;
		x509_free_certificate(cert);
	}
	mpi_free(ctx->sinfo->sig.mpi[0]);
	kfree(ctx->sinfo->sig.digest);
	kfree(ctx->sinfo);
	pkcs7_free_signed_info(ctx->sinfo);
out_no_sinfo:
	pkcs7_free_message(ctx->msg);
out_no_msg:
	kfree(ctx);
out_no_ctx:
	return msg;

error_decode:
	mpi_free(ctx->sinfo->sig.mpi[0]);
	kfree(ctx->sinfo->sig.digest);
	kfree(ctx->sinfo);
error_no_sinfo:
	kfree(ctx);
error_no_ctx:
	pkcs7_free_message(msg);
error_no_sig:
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(pkcs7_parse_message);

+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ static int key_get_type_from_user(char *type,
		return ret;
	if (ret == 0 || ret >= len)
		return -EINVAL;
	if (type[0] == '.')
		return -EPERM;
	type[len - 1] = '\0';
	return 0;
}