KEYS: Call ->free_preparse() even after ->preparse() returns an error
authorDavid Howells <dhowells@redhat.com>
Fri, 18 Jul 2014 17:56:34 +0000 (18:56 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 22 Jul 2014 20:46:12 +0000 (21:46 +0100)
Call the ->free_preparse() key type op even after ->preparse() returns an
error as it does cleaning up type stuff.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Steve Dickson <steved@redhat.com>
Acked-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Sage Weil <sage@redhat.com>
Documentation/security/keys.txt
security/keys/key.c

index 315cf96a41a2ebd30e586bef2b81a87eb0cf5c8e..8727c194ca16a56f483b2f0cd2712654c0b948b4 100644 (file)
@@ -1176,7 +1176,9 @@ The structure has a number of fields, some of which are mandatory:
      This method is only required if the preparse() method is provided,
      otherwise it is unused.  It cleans up anything attached to the
      description, type_data and payload fields of the key_preparsed_payload
-     struct as filled in by the preparse() method.
+     struct as filled in by the preparse() method.  It will always be called
+     after preparse() returns successfully, even if instantiate() or update()
+     succeed.
 
 
  (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
index 755fb02df5af47e99e2f143ae30b9e20bbf05f97..b90a68c4e2c4277035b21f873af64efcd95bf782 100644 (file)
@@ -494,7 +494,7 @@ int key_instantiate_and_link(struct key *key,
        if (keyring) {
                ret = __key_link_begin(keyring, &key->index_key, &edit);
                if (ret < 0)
-                       goto error_free_preparse;
+                       goto error;
        }
 
        ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
@@ -502,10 +502,9 @@ int key_instantiate_and_link(struct key *key,
        if (keyring)
                __key_link_end(keyring, &key->index_key, edit);
 
-error_free_preparse:
+error:
        if (key->type->preparse)
                key->type->free_preparse(&prep);
-error:
        return ret;
 }
 
@@ -822,7 +821,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                ret = index_key.type->preparse(&prep);
                if (ret < 0) {
                        key_ref = ERR_PTR(ret);
-                       goto error_put_type;
+                       goto error_free_prep;
                }
                if (!index_key.description)
                        index_key.description = prep.description;
@@ -964,9 +963,9 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
 
        up_write(&key->sem);
 
+error:
        if (key->type->preparse)
                key->type->free_preparse(&prep);
-error:
        return ret;
 }
 EXPORT_SYMBOL(key_update);