*/
 struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
 {
-       struct x509_certificate *cert;
-       struct x509_parse_context *ctx;
+       struct x509_certificate *cert __free(x509_free_certificate);
+       struct x509_parse_context *ctx __free(kfree) = NULL;
        struct asymmetric_key_id *kid;
        long ret;
 
-       ret = -ENOMEM;
        cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL);
+       assume(!IS_ERR(cert)); /* Avoid gratuitous IS_ERR() check on return */
        if (!cert)
-               goto error_no_cert;
+               return ERR_PTR(-ENOMEM);
        cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
        if (!cert->pub)
-               goto error_no_ctx;
+               return ERR_PTR(-ENOMEM);
        cert->sig = kzalloc(sizeof(struct public_key_signature), GFP_KERNEL);
        if (!cert->sig)
-               goto error_no_ctx;
+               return ERR_PTR(-ENOMEM);
        ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
        if (!ctx)
-               goto error_no_ctx;
+               return ERR_PTR(-ENOMEM);
 
        ctx->cert = cert;
        ctx->data = (unsigned long)data;
        /* Attempt to decode the certificate */
        ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen);
        if (ret < 0)
-               goto error_decode;
+               return ERR_PTR(ret);
 
        /* Decode the AuthorityKeyIdentifier */
        if (ctx->raw_akid) {
                                       ctx->raw_akid, ctx->raw_akid_size);
                if (ret < 0) {
                        pr_warn("Couldn't decode AuthKeyIdentifier\n");
-                       goto error_decode;
+                       return ERR_PTR(ret);
                }
        }
 
-       ret = -ENOMEM;
        cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
        if (!cert->pub->key)
-               goto error_decode;
+               return ERR_PTR(-ENOMEM);
 
        cert->pub->keylen = ctx->key_size;
 
        cert->pub->params = kmemdup(ctx->params, ctx->params_size, GFP_KERNEL);
        if (!cert->pub->params)
-               goto error_decode;
+               return ERR_PTR(-ENOMEM);
 
        cert->pub->paramlen = ctx->params_size;
        cert->pub->algo = ctx->key_algo;
        /* Grab the signature bits */
        ret = x509_get_sig_params(cert);
        if (ret < 0)
-               goto error_decode;
+               return ERR_PTR(ret);
 
        /* Generate cert issuer + serial number key ID */
        kid = asymmetric_key_generate_id(cert->raw_serial,
                                         cert->raw_serial_size,
                                         cert->raw_issuer,
                                         cert->raw_issuer_size);
-       if (IS_ERR(kid)) {
-               ret = PTR_ERR(kid);
-               goto error_decode;
-       }
+       if (IS_ERR(kid))
+               return ERR_CAST(kid);
        cert->id = kid;
 
        /* Detect self-signed certificates */
        ret = x509_check_for_self_signed(cert);
        if (ret < 0)
-               goto error_decode;
-
-       kfree(ctx);
-       return cert;
+               return ERR_PTR(ret);
 
-error_decode:
-       kfree(ctx);
-error_no_ctx:
-       x509_free_certificate(cert);
-error_no_cert:
-       return ERR_PTR(ret);
+       return_ptr(cert);
 }
 EXPORT_SYMBOL_GPL(x509_cert_parse);
 
 
  * Written by David Howells (dhowells@redhat.com)
  */
 
+#include <linux/cleanup.h>
 #include <linux/time.h>
 #include <crypto/public_key.h>
 #include <keys/asymmetric-type.h>
  * x509_cert_parser.c
  */
 extern void x509_free_certificate(struct x509_certificate *cert);
+DEFINE_FREE(x509_free_certificate, struct x509_certificate *,
+           if (!IS_ERR(_T)) x509_free_certificate(_T))
 extern struct x509_certificate *x509_cert_parse(const void *data, size_t datalen);
 extern int x509_decode_time(time64_t *_t,  size_t hdrlen,
                            unsigned char tag,
 
  */
 static int x509_key_preparse(struct key_preparsed_payload *prep)
 {
-       struct asymmetric_key_ids *kids;
-       struct x509_certificate *cert;
+       struct x509_certificate *cert __free(x509_free_certificate);
+       struct asymmetric_key_ids *kids __free(kfree) = NULL;
+       char *p, *desc __free(kfree) = NULL;
        const char *q;
        size_t srlen, sulen;
-       char *desc = NULL, *p;
-       int ret;
 
        cert = x509_cert_parse(prep->data, prep->datalen);
        if (IS_ERR(cert))
        }
 
        /* Don't permit addition of blacklisted keys */
-       ret = -EKEYREJECTED;
        if (cert->blacklisted)
-               goto error_free_cert;
+               return -EKEYREJECTED;
 
        /* Propose a description */
        sulen = strlen(cert->subject);
                q = cert->raw_serial;
        }
 
-       ret = -ENOMEM;
        desc = kmalloc(sulen + 2 + srlen * 2 + 1, GFP_KERNEL);
        if (!desc)
-               goto error_free_cert;
+               return -ENOMEM;
        p = memcpy(desc, cert->subject, sulen);
        p += sulen;
        *p++ = ':';
 
        kids = kmalloc(sizeof(struct asymmetric_key_ids), GFP_KERNEL);
        if (!kids)
-               goto error_free_desc;
+               return -ENOMEM;
        kids->id[0] = cert->id;
        kids->id[1] = cert->skid;
        kids->id[2] = asymmetric_key_generate_id(cert->raw_subject,
                                                 cert->raw_subject_size,
                                                 "", 0);
-       if (IS_ERR(kids->id[2])) {
-               ret = PTR_ERR(kids->id[2]);
-               goto error_free_kids;
-       }
+       if (IS_ERR(kids->id[2]))
+               return PTR_ERR(kids->id[2]);
 
        /* We're pinning the module by being linked against it */
        __module_get(public_key_subtype.owner);
        cert->sig = NULL;
        desc = NULL;
        kids = NULL;
-       ret = 0;
-
-error_free_kids:
-       kfree(kids);
-error_free_desc:
-       kfree(desc);
-error_free_cert:
-       x509_free_certificate(cert);
-       return ret;
+       return 0;
 }
 
 static struct asymmetric_key_parser x509_key_parser = {