diff options
Diffstat (limited to 'security/keys/request_key_auth.c')
-rw-r--r-- | security/keys/request_key_auth.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index cce6ba6b0323..cb9817ced3fd 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | static int request_key_auth_instantiate(struct key *, const void *, size_t); | 21 | static int request_key_auth_instantiate(struct key *, const void *, size_t); |
22 | static void request_key_auth_describe(const struct key *, struct seq_file *); | 22 | static void request_key_auth_describe(const struct key *, struct seq_file *); |
23 | static void request_key_auth_revoke(struct key *); | ||
23 | static void request_key_auth_destroy(struct key *); | 24 | static void request_key_auth_destroy(struct key *); |
24 | static long request_key_auth_read(const struct key *, char __user *, size_t); | 25 | static long request_key_auth_read(const struct key *, char __user *, size_t); |
25 | 26 | ||
@@ -31,6 +32,7 @@ struct key_type key_type_request_key_auth = { | |||
31 | .def_datalen = sizeof(struct request_key_auth), | 32 | .def_datalen = sizeof(struct request_key_auth), |
32 | .instantiate = request_key_auth_instantiate, | 33 | .instantiate = request_key_auth_instantiate, |
33 | .describe = request_key_auth_describe, | 34 | .describe = request_key_auth_describe, |
35 | .revoke = request_key_auth_revoke, | ||
34 | .destroy = request_key_auth_destroy, | 36 | .destroy = request_key_auth_destroy, |
35 | .read = request_key_auth_read, | 37 | .read = request_key_auth_read, |
36 | }; | 38 | }; |
@@ -93,6 +95,24 @@ static long request_key_auth_read(const struct key *key, | |||
93 | 95 | ||
94 | /*****************************************************************************/ | 96 | /*****************************************************************************/ |
95 | /* | 97 | /* |
98 | * handle revocation of an authorisation token key | ||
99 | * - called with the key sem write-locked | ||
100 | */ | ||
101 | static void request_key_auth_revoke(struct key *key) | ||
102 | { | ||
103 | struct request_key_auth *rka = key->payload.data; | ||
104 | |||
105 | kenter("{%d}", key->serial); | ||
106 | |||
107 | if (rka->context) { | ||
108 | put_task_struct(rka->context); | ||
109 | rka->context = NULL; | ||
110 | } | ||
111 | |||
112 | } /* end request_key_auth_revoke() */ | ||
113 | |||
114 | /*****************************************************************************/ | ||
115 | /* | ||
96 | * destroy an instantiation authorisation token key | 116 | * destroy an instantiation authorisation token key |
97 | */ | 117 | */ |
98 | static void request_key_auth_destroy(struct key *key) | 118 | static void request_key_auth_destroy(struct key *key) |
@@ -101,6 +121,11 @@ static void request_key_auth_destroy(struct key *key) | |||
101 | 121 | ||
102 | kenter("{%d}", key->serial); | 122 | kenter("{%d}", key->serial); |
103 | 123 | ||
124 | if (rka->context) { | ||
125 | put_task_struct(rka->context); | ||
126 | rka->context = NULL; | ||
127 | } | ||
128 | |||
104 | key_put(rka->target_key); | 129 | key_put(rka->target_key); |
105 | kfree(rka); | 130 | kfree(rka); |
106 | 131 | ||
@@ -131,14 +156,26 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
131 | * another process */ | 156 | * another process */ |
132 | if (current->request_key_auth) { | 157 | if (current->request_key_auth) { |
133 | /* it is - use that instantiation context here too */ | 158 | /* it is - use that instantiation context here too */ |
159 | down_read(¤t->request_key_auth->sem); | ||
160 | |||
161 | /* if the auth key has been revoked, then the key we're | ||
162 | * servicing is already instantiated */ | ||
163 | if (test_bit(KEY_FLAG_REVOKED, | ||
164 | ¤t->request_key_auth->flags)) | ||
165 | goto auth_key_revoked; | ||
166 | |||
134 | irka = current->request_key_auth->payload.data; | 167 | irka = current->request_key_auth->payload.data; |
135 | rka->context = irka->context; | 168 | rka->context = irka->context; |
136 | rka->pid = irka->pid; | 169 | rka->pid = irka->pid; |
170 | get_task_struct(rka->context); | ||
171 | |||
172 | up_read(¤t->request_key_auth->sem); | ||
137 | } | 173 | } |
138 | else { | 174 | else { |
139 | /* it isn't - use this process as the context */ | 175 | /* it isn't - use this process as the context */ |
140 | rka->context = current; | 176 | rka->context = current; |
141 | rka->pid = current->pid; | 177 | rka->pid = current->pid; |
178 | get_task_struct(rka->context); | ||
142 | } | 179 | } |
143 | 180 | ||
144 | rka->target_key = key_get(target); | 181 | rka->target_key = key_get(target); |
@@ -148,7 +185,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
148 | sprintf(desc, "%x", target->serial); | 185 | sprintf(desc, "%x", target->serial); |
149 | 186 | ||
150 | authkey = key_alloc(&key_type_request_key_auth, desc, | 187 | authkey = key_alloc(&key_type_request_key_auth, desc, |
151 | current->fsuid, current->fsgid, | 188 | current->fsuid, current->fsgid, current, |
152 | KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | | 189 | KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | |
153 | KEY_USR_VIEW, 1); | 190 | KEY_USR_VIEW, 1); |
154 | if (IS_ERR(authkey)) { | 191 | if (IS_ERR(authkey)) { |
@@ -161,9 +198,15 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
161 | if (ret < 0) | 198 | if (ret < 0) |
162 | goto error_inst; | 199 | goto error_inst; |
163 | 200 | ||
164 | kleave(" = {%d})", authkey->serial); | 201 | kleave(" = {%d}", authkey->serial); |
165 | return authkey; | 202 | return authkey; |
166 | 203 | ||
204 | auth_key_revoked: | ||
205 | up_read(¤t->request_key_auth->sem); | ||
206 | kfree(rka); | ||
207 | kleave("= -EKEYREVOKED"); | ||
208 | return ERR_PTR(-EKEYREVOKED); | ||
209 | |||
167 | error_inst: | 210 | error_inst: |
168 | key_revoke(authkey); | 211 | key_revoke(authkey); |
169 | key_put(authkey); | 212 | key_put(authkey); |