diff options
author | David Howells | 2014-09-16 17:32:16 +0100 |
---|---|---|
committer | David Howells | 2014-09-16 17:32:16 +0100 |
commit | 68c45c7feaf1a8adebc6d9d77aa0a2018d974085 (patch) | |
tree | 3723e1d847b0626e07837db7c648ba63ade7e1a5 | |
parent | ac60ab4b4968b54fb5af20eac9dd78e36ad910c1 (diff) | |
parent | cecf5d2e1208da512a4c951c24acd66c54a4d06c (diff) |
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: David Howells <dhowells@redhat.coM>
-rw-r--r-- | crypto/asymmetric_keys/pkcs7_parser.c | 61 | ||||
-rw-r--r-- | security/keys/keyctl.c | 2 |
2 files changed, 35 insertions, 28 deletions
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 42e56aa7d277..1e9861da7ee4 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); } @@ -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); 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; } |