Browse Source

KEYS: Call ->free_preparse() even after ->preparse() returns an error

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>
David Howells 11 years ago
parent
commit
4d8c0250b8
2 changed files with 7 additions and 6 deletions
  1. 3 1
      Documentation/security/keys.txt
  2. 4 5
      security/keys/key.c

+ 3 - 1
Documentation/security/keys.txt

@@ -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,
      This method is only required if the preparse() method is provided,
      otherwise it is unused.  It cleans up anything attached to the
      otherwise it is unused.  It cleans up anything attached to the
      description, type_data and payload fields of the key_preparsed_payload
      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);
  (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);

+ 4 - 5
security/keys/key.c

@@ -494,7 +494,7 @@ int key_instantiate_and_link(struct key *key,
 	if (keyring) {
 	if (keyring) {
 		ret = __key_link_begin(keyring, &key->index_key, &edit);
 		ret = __key_link_begin(keyring, &key->index_key, &edit);
 		if (ret < 0)
 		if (ret < 0)
-			goto error_free_preparse;
+			goto error;
 	}
 	}
 
 
 	ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
 	ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
@@ -502,10 +502,9 @@ int key_instantiate_and_link(struct key *key,
 	if (keyring)
 	if (keyring)
 		__key_link_end(keyring, &key->index_key, edit);
 		__key_link_end(keyring, &key->index_key, edit);
 
 
-error_free_preparse:
+error:
 	if (key->type->preparse)
 	if (key->type->preparse)
 		key->type->free_preparse(&prep);
 		key->type->free_preparse(&prep);
-error:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -822,7 +821,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
 		ret = index_key.type->preparse(&prep);
 		ret = index_key.type->preparse(&prep);
 		if (ret < 0) {
 		if (ret < 0) {
 			key_ref = ERR_PTR(ret);
 			key_ref = ERR_PTR(ret);
-			goto error_put_type;
+			goto error_free_prep;
 		}
 		}
 		if (!index_key.description)
 		if (!index_key.description)
 			index_key.description = prep.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);
 	up_write(&key->sem);
 
 
+error:
 	if (key->type->preparse)
 	if (key->type->preparse)
 		key->type->free_preparse(&prep);
 		key->type->free_preparse(&prep);
-error:
 	return ret;
 	return ret;
 }
 }
 EXPORT_SYMBOL(key_update);
 EXPORT_SYMBOL(key_update);