Merge tag 'keys-fixes-20140916' into keys-next
authorDavid Howells <dhowells@redhat.com>
Tue, 16 Sep 2014 16:32:16 +0000 (17:32 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 16 Sep 2014 16:32:16 +0000 (17:32 +0100)
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>
crypto/asymmetric_keys/pkcs7_parser.c
security/keys/keyctl.c

index 42e56aa..1e9861d 100644 (file)
@@ -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);
 
index e26f860..eff88a5 100644 (file)
@@ -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;
 }