aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/user_defined.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-09-13 08:06:29 -0400
committerRusty Russell <rusty@rustcorp.com.au>2012-10-07 23:19:48 -0400
commitcf7f601c067994f371ba77721d1e45fce61a4569 (patch)
tree4ff5a12ae84cf47a9815c3e3979341a66360cb31 /security/keys/user_defined.c
parent9bb9c3be56834653878f766f471fa1c20e562f4c (diff)
KEYS: Add payload preparsing opportunity prior to key instantiate or update
Give the key type the opportunity to preparse the payload prior to the instantiation and update routines being called. This is done with the provision of two new key type operations: int (*preparse)(struct key_preparsed_payload *prep); void (*free_preparse)(struct key_preparsed_payload *prep); If the first operation is present, then it is called before key creation (in the add/update case) or before the key semaphore is taken (in the update and instantiate cases). The second operation is called to clean up if the first was called. preparse() is given the opportunity to fill in the following structure: struct key_preparsed_payload { char *description; void *type_data[2]; void *payload; const void *data; size_t datalen; size_t quotalen; }; Before the preparser is called, the first three fields will have been cleared, the payload pointer and size will be stored in data and datalen and the default quota size from the key_type struct will be stored into quotalen. The preparser may parse the payload in any way it likes and may store data in the type_data[] and payload fields for use by the instantiate() and update() ops. The preparser may also propose a description for the key by attaching it as a string to the description field. This can be used by passing a NULL or "" description to the add_key() system call or the key_create_or_update() function. This cannot work with request_key() as that required the description to tell the upcall about the key to be created. This, for example permits keys that store PGP public keys to generate their own name from the user ID and public key fingerprint in the key. The instantiate() and update() operations are then modified to look like this: int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); int (*update)(struct key *key, struct key_preparsed_payload *prep); and the new payload data is passed in *prep, whether or not it was preparsed. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'security/keys/user_defined.c')
-rw-r--r--security/keys/user_defined.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index c7660a25a3e4..55dc88939185 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -58,13 +58,14 @@ EXPORT_SYMBOL_GPL(key_type_logon);
58/* 58/*
59 * instantiate a user defined key 59 * instantiate a user defined key
60 */ 60 */
61int user_instantiate(struct key *key, const void *data, size_t datalen) 61int user_instantiate(struct key *key, struct key_preparsed_payload *prep)
62{ 62{
63 struct user_key_payload *upayload; 63 struct user_key_payload *upayload;
64 size_t datalen = prep->datalen;
64 int ret; 65 int ret;
65 66
66 ret = -EINVAL; 67 ret = -EINVAL;
67 if (datalen <= 0 || datalen > 32767 || !data) 68 if (datalen <= 0 || datalen > 32767 || !prep->data)
68 goto error; 69 goto error;
69 70
70 ret = key_payload_reserve(key, datalen); 71 ret = key_payload_reserve(key, datalen);
@@ -78,7 +79,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen)
78 79
79 /* attach the data */ 80 /* attach the data */
80 upayload->datalen = datalen; 81 upayload->datalen = datalen;
81 memcpy(upayload->data, data, datalen); 82 memcpy(upayload->data, prep->data, datalen);
82 rcu_assign_keypointer(key, upayload); 83 rcu_assign_keypointer(key, upayload);
83 ret = 0; 84 ret = 0;
84 85
@@ -92,13 +93,14 @@ EXPORT_SYMBOL_GPL(user_instantiate);
92 * update a user defined key 93 * update a user defined key
93 * - the key's semaphore is write-locked 94 * - the key's semaphore is write-locked
94 */ 95 */
95int user_update(struct key *key, const void *data, size_t datalen) 96int user_update(struct key *key, struct key_preparsed_payload *prep)
96{ 97{
97 struct user_key_payload *upayload, *zap; 98 struct user_key_payload *upayload, *zap;
99 size_t datalen = prep->datalen;
98 int ret; 100 int ret;
99 101
100 ret = -EINVAL; 102 ret = -EINVAL;
101 if (datalen <= 0 || datalen > 32767 || !data) 103 if (datalen <= 0 || datalen > 32767 || !prep->data)
102 goto error; 104 goto error;
103 105
104 /* construct a replacement payload */ 106 /* construct a replacement payload */
@@ -108,7 +110,7 @@ int user_update(struct key *key, const void *data, size_t datalen)
108 goto error; 110 goto error;
109 111
110 upayload->datalen = datalen; 112 upayload->datalen = datalen;
111 memcpy(upayload->data, data, datalen); 113 memcpy(upayload->data, prep->data, datalen);
112 114
113 /* check the quota and attach the new data */ 115 /* check the quota and attach the new data */
114 zap = upayload; 116 zap = upayload;