From 54e2c2c1a9d6cbb270b0999a38545fa9a69bee43 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 16 Sep 2014 17:29:03 +0100 Subject: [PATCH 1/3] KEYS: Reinstate EPERM for a key type name beginning with a '.' Reinstate the generation of EPERM for a key type name beginning with a '.' in a userspace call. Types whose name begins with a '.' are internal only. The test was removed by: commit a4e3b8d79a5c6d40f4a9703abf7fe3abcc6c3b8d Author: Mimi Zohar Date: Thu May 22 14:02:23 2014 -0400 Subject: KEYS: special dot prefixed keyring name bug fix I think we want to keep the restriction on type name so that userspace can't add keys of a special internal type. Note that removal of the test causes several of the tests in the keyutils testsuite to fail. Signed-off-by: David Howells Acked-by: Vivek Goyal cc: Mimi Zohar --- security/keys/keyctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index e26f860e5f2e..eff88a5f5d40 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -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; } From 3cd0920cde6a726b9965b60184f9d5a54358304d Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 16 Sep 2014 17:29:03 +0100 Subject: [PATCH 2/3] PKCS#7: Provide a single place to do signed info block freeing The code to free a signed info block is repeated several times, so move the code to do it into a function of its own. This gives us a place to add clean ups for stuff that gets added to pkcs7_signed_info. Signed-off-by: David Howells Acked-by: Vivek Goyal --- crypto/asymmetric_keys/pkcs7_parser.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 42e56aa7d277..4c4ea35c338b 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -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); } @@ -100,16 +110,12 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen) 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); kfree(ctx); return msg; error_decode: - mpi_free(ctx->sinfo->sig.mpi[0]); - kfree(ctx->sinfo->sig.digest); - kfree(ctx->sinfo); + pkcs7_free_signed_info(ctx->sinfo); error_no_sinfo: kfree(ctx); error_no_ctx: From cecf5d2e1208da512a4c951c24acd66c54a4d06c Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 16 Sep 2014 17:29:03 +0100 Subject: [PATCH 3/3] PKCS#7: Fix the parser cleanup to drain parsed out X.509 certs Fix the parser cleanup code to drain parsed out X.509 certs in the case that the decode fails and we jump to error_decode. The function is rearranged so that the same cleanup code is used in the success case as the error case - just that the message descriptor under construction is only released if it is still pointed to by the context struct at that point. Signed-off-by: David Howells Acked-by: Vivek Goyal --- crypto/asymmetric_keys/pkcs7_parser.c | 39 +++++++++++++-------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 4c4ea35c338b..1e9861da7ee4 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -81,47 +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); } 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: - pkcs7_free_signed_info(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);