Skip to content

Commit

Permalink
KEYS: user: Use key preparsing
Browse files Browse the repository at this point in the history
Make use of key preparsing in user-defined and logon keys so that quota size
determination can take place prior to keyring locking when a key is being
added.

Also the idmapper key types need to change to match as they use the
user-defined key type routines.

Signed-off-by: David Howells <[email protected]>
Acked-by: Steve Dickson <[email protected]>
Acked-by: Jeff Layton <[email protected]>
  • Loading branch information
dhowells committed Jul 22, 2014
1 parent 4d8c025 commit f916778
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 22 deletions.
8 changes: 6 additions & 2 deletions fs/nfs/idmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen)

static struct key_type key_type_id_resolver = {
.name = "id_resolver",
.instantiate = user_instantiate,
.preparse = user_preparse,
.free_preparse = user_free_preparse,
.instantiate = generic_key_instantiate,
.match = user_match,
.revoke = user_revoke,
.destroy = user_destroy,
Expand Down Expand Up @@ -394,7 +396,9 @@ static const struct rpc_pipe_ops idmap_upcall_ops = {

static struct key_type key_type_id_resolver_legacy = {
.name = "id_legacy",
.instantiate = user_instantiate,
.preparse = user_preparse,
.free_preparse = user_free_preparse,
.instantiate = generic_key_instantiate,
.match = user_match,
.revoke = user_revoke,
.destroy = user_destroy,
Expand Down
3 changes: 2 additions & 1 deletion include/keys/user-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ extern struct key_type key_type_logon;

struct key_preparsed_payload;

extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep);
extern int user_preparse(struct key_preparsed_payload *prep);
extern void user_free_preparse(struct key_preparsed_payload *prep);
extern int user_update(struct key *key, struct key_preparsed_payload *prep);
extern int user_match(const struct key *key, const void *criterion);
extern void user_revoke(struct key *key);
Expand Down
41 changes: 22 additions & 19 deletions security/keys/user_defined.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ static int logon_vet_description(const char *desc);
struct key_type key_type_user = {
.name = "user",
.def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
.instantiate = user_instantiate,
.preparse = user_preparse,
.free_preparse = user_free_preparse,
.instantiate = generic_key_instantiate,
.update = user_update,
.match = user_match,
.revoke = user_revoke,
Expand All @@ -47,7 +49,9 @@ EXPORT_SYMBOL_GPL(key_type_user);
struct key_type key_type_logon = {
.name = "logon",
.def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
.instantiate = user_instantiate,
.preparse = user_preparse,
.free_preparse = user_free_preparse,
.instantiate = generic_key_instantiate,
.update = user_update,
.match = user_match,
.revoke = user_revoke,
Expand All @@ -58,38 +62,37 @@ struct key_type key_type_logon = {
EXPORT_SYMBOL_GPL(key_type_logon);

/*
* instantiate a user defined key
* Preparse a user defined key payload
*/
int user_instantiate(struct key *key, struct key_preparsed_payload *prep)
int user_preparse(struct key_preparsed_payload *prep)
{
struct user_key_payload *upayload;
size_t datalen = prep->datalen;
int ret;

ret = -EINVAL;
if (datalen <= 0 || datalen > 32767 || !prep->data)
goto error;

ret = key_payload_reserve(key, datalen);
if (ret < 0)
goto error;
return -EINVAL;

ret = -ENOMEM;
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
if (!upayload)
goto error;
return -ENOMEM;

/* attach the data */
prep->quotalen = datalen;
prep->payload[0] = upayload;
upayload->datalen = datalen;
memcpy(upayload->data, prep->data, datalen);
rcu_assign_keypointer(key, upayload);
ret = 0;

error:
return ret;
return 0;
}
EXPORT_SYMBOL_GPL(user_preparse);

EXPORT_SYMBOL_GPL(user_instantiate);
/*
* Free a preparse of a user defined key payload
*/
void user_free_preparse(struct key_preparsed_payload *prep)
{
kfree(prep->payload[0]);
}
EXPORT_SYMBOL_GPL(user_free_preparse);

/*
* update a user defined key
Expand Down

0 comments on commit f916778

Please sign in to comment.