diff options
Diffstat (limited to 'fs/ecryptfs/messaging.c')
-rw-r--r-- | fs/ecryptfs/messaging.c | 479 |
1 files changed, 318 insertions, 161 deletions
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index 9cc2aec27b0d..c6038bd60897 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /** |
2 | * eCryptfs: Linux filesystem encryption layer | 2 | * eCryptfs: Linux filesystem encryption layer |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2006 International Business Machines Corp. | 4 | * Copyright (C) 2004-2008 International Business Machines Corp. |
5 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | 5 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> |
6 | * Tyler Hicks <tyhicks@ou.edu> | 6 | * Tyler Hicks <tyhicks@ou.edu> |
7 | * | 7 | * |
@@ -26,13 +26,13 @@ static LIST_HEAD(ecryptfs_msg_ctx_free_list); | |||
26 | static LIST_HEAD(ecryptfs_msg_ctx_alloc_list); | 26 | static LIST_HEAD(ecryptfs_msg_ctx_alloc_list); |
27 | static struct mutex ecryptfs_msg_ctx_lists_mux; | 27 | static struct mutex ecryptfs_msg_ctx_lists_mux; |
28 | 28 | ||
29 | static struct hlist_head *ecryptfs_daemon_id_hash; | 29 | static struct hlist_head *ecryptfs_daemon_hash; |
30 | static struct mutex ecryptfs_daemon_id_hash_mux; | 30 | struct mutex ecryptfs_daemon_hash_mux; |
31 | static int ecryptfs_hash_buckets; | 31 | static int ecryptfs_hash_buckets; |
32 | #define ecryptfs_uid_hash(uid) \ | 32 | #define ecryptfs_uid_hash(uid) \ |
33 | hash_long((unsigned long)uid, ecryptfs_hash_buckets) | 33 | hash_long((unsigned long)uid, ecryptfs_hash_buckets) |
34 | 34 | ||
35 | static unsigned int ecryptfs_msg_counter; | 35 | static u32 ecryptfs_msg_counter; |
36 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | 36 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; |
37 | 37 | ||
38 | /** | 38 | /** |
@@ -40,9 +40,10 @@ static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | |||
40 | * @msg_ctx: The context that was acquired from the free list | 40 | * @msg_ctx: The context that was acquired from the free list |
41 | * | 41 | * |
42 | * Acquires a context element from the free list and locks the mutex | 42 | * Acquires a context element from the free list and locks the mutex |
43 | * on the context. Returns zero on success; non-zero on error or upon | 43 | * on the context. Sets the msg_ctx task to current. Returns zero on |
44 | * failure to acquire a free context element. Be sure to lock the | 44 | * success; non-zero on error or upon failure to acquire a free |
45 | * list mutex before calling. | 45 | * context element. Must be called with ecryptfs_msg_ctx_lists_mux |
46 | * held. | ||
46 | */ | 47 | */ |
47 | static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx) | 48 | static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx) |
48 | { | 49 | { |
@@ -50,11 +51,11 @@ static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx) | |||
50 | int rc; | 51 | int rc; |
51 | 52 | ||
52 | if (list_empty(&ecryptfs_msg_ctx_free_list)) { | 53 | if (list_empty(&ecryptfs_msg_ctx_free_list)) { |
53 | ecryptfs_printk(KERN_WARNING, "The eCryptfs free " | 54 | printk(KERN_WARNING "%s: The eCryptfs free " |
54 | "context list is empty. It may be helpful to " | 55 | "context list is empty. It may be helpful to " |
55 | "specify the ecryptfs_message_buf_len " | 56 | "specify the ecryptfs_message_buf_len " |
56 | "parameter to be greater than the current " | 57 | "parameter to be greater than the current " |
57 | "value of [%d]\n", ecryptfs_message_buf_len); | 58 | "value of [%d]\n", __func__, ecryptfs_message_buf_len); |
58 | rc = -ENOMEM; | 59 | rc = -ENOMEM; |
59 | goto out; | 60 | goto out; |
60 | } | 61 | } |
@@ -75,8 +76,7 @@ out: | |||
75 | * ecryptfs_msg_ctx_free_to_alloc | 76 | * ecryptfs_msg_ctx_free_to_alloc |
76 | * @msg_ctx: The context to move from the free list to the alloc list | 77 | * @msg_ctx: The context to move from the free list to the alloc list |
77 | * | 78 | * |
78 | * Be sure to lock the list mutex and the context mutex before | 79 | * Must be called with ecryptfs_msg_ctx_lists_mux held. |
79 | * calling. | ||
80 | */ | 80 | */ |
81 | static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx) | 81 | static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx) |
82 | { | 82 | { |
@@ -89,36 +89,37 @@ static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx) | |||
89 | * ecryptfs_msg_ctx_alloc_to_free | 89 | * ecryptfs_msg_ctx_alloc_to_free |
90 | * @msg_ctx: The context to move from the alloc list to the free list | 90 | * @msg_ctx: The context to move from the alloc list to the free list |
91 | * | 91 | * |
92 | * Be sure to lock the list mutex and the context mutex before | 92 | * Must be called with ecryptfs_msg_ctx_lists_mux held. |
93 | * calling. | ||
94 | */ | 93 | */ |
95 | static void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | 94 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) |
96 | { | 95 | { |
97 | list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list); | 96 | list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list); |
98 | if (msg_ctx->msg) | 97 | if (msg_ctx->msg) |
99 | kfree(msg_ctx->msg); | 98 | kfree(msg_ctx->msg); |
99 | msg_ctx->msg = NULL; | ||
100 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE; | 100 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE; |
101 | } | 101 | } |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * ecryptfs_find_daemon_id | 104 | * ecryptfs_find_daemon_by_euid |
105 | * @uid: The user id which maps to the desired daemon id | 105 | * @euid: The effective user id which maps to the desired daemon id |
106 | * @id: If return value is zero, points to the desired daemon id | 106 | * @daemon: If return value is zero, points to the desired daemon pointer |
107 | * pointer | ||
108 | * | 107 | * |
109 | * Search the hash list for the given user id. Returns zero if the | 108 | * Must be called with ecryptfs_daemon_hash_mux held. |
110 | * user id exists in the list; non-zero otherwise. The daemon id hash | 109 | * |
111 | * mutex should be held before calling this function. | 110 | * Search the hash list for the given user id. |
111 | * | ||
112 | * Returns zero if the user id exists in the list; non-zero otherwise. | ||
112 | */ | 113 | */ |
113 | static int ecryptfs_find_daemon_id(uid_t uid, struct ecryptfs_daemon_id **id) | 114 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid) |
114 | { | 115 | { |
115 | struct hlist_node *elem; | 116 | struct hlist_node *elem; |
116 | int rc; | 117 | int rc; |
117 | 118 | ||
118 | hlist_for_each_entry(*id, elem, | 119 | hlist_for_each_entry(*daemon, elem, |
119 | &ecryptfs_daemon_id_hash[ecryptfs_uid_hash(uid)], | 120 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], |
120 | id_chain) { | 121 | euid_chain) { |
121 | if ((*id)->uid == uid) { | 122 | if ((*daemon)->euid == euid) { |
122 | rc = 0; | 123 | rc = 0; |
123 | goto out; | 124 | goto out; |
124 | } | 125 | } |
@@ -128,181 +129,291 @@ out: | |||
128 | return rc; | 129 | return rc; |
129 | } | 130 | } |
130 | 131 | ||
131 | static int ecryptfs_send_raw_message(unsigned int transport, u16 msg_type, | 132 | static int |
132 | pid_t pid) | 133 | ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len, |
134 | u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx); | ||
135 | |||
136 | /** | ||
137 | * ecryptfs_send_raw_message | ||
138 | * @transport: Transport type | ||
139 | * @msg_type: Message type | ||
140 | * @daemon: Daemon struct for recipient of message | ||
141 | * | ||
142 | * A raw message is one that does not include an ecryptfs_message | ||
143 | * struct. It simply has a type. | ||
144 | * | ||
145 | * Must be called with ecryptfs_daemon_hash_mux held. | ||
146 | * | ||
147 | * Returns zero on success; non-zero otherwise | ||
148 | */ | ||
149 | static int ecryptfs_send_raw_message(unsigned int transport, u8 msg_type, | ||
150 | struct ecryptfs_daemon *daemon) | ||
133 | { | 151 | { |
152 | struct ecryptfs_msg_ctx *msg_ctx; | ||
134 | int rc; | 153 | int rc; |
135 | 154 | ||
136 | switch(transport) { | 155 | switch(transport) { |
137 | case ECRYPTFS_TRANSPORT_NETLINK: | 156 | case ECRYPTFS_TRANSPORT_NETLINK: |
138 | rc = ecryptfs_send_netlink(NULL, 0, NULL, msg_type, 0, pid); | 157 | rc = ecryptfs_send_netlink(NULL, 0, NULL, msg_type, 0, |
158 | daemon->pid); | ||
159 | break; | ||
160 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
161 | rc = ecryptfs_send_message_locked(transport, NULL, 0, msg_type, | ||
162 | &msg_ctx); | ||
163 | if (rc) { | ||
164 | printk(KERN_ERR "%s: Error whilst attempting to send " | ||
165 | "message via procfs; rc = [%d]\n", __func__, rc); | ||
166 | goto out; | ||
167 | } | ||
168 | /* Raw messages are logically context-free (e.g., no | ||
169 | * reply is expected), so we set the state of the | ||
170 | * ecryptfs_msg_ctx object to indicate that it should | ||
171 | * be freed as soon as the transport sends out the message. */ | ||
172 | mutex_lock(&msg_ctx->mux); | ||
173 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY; | ||
174 | mutex_unlock(&msg_ctx->mux); | ||
139 | break; | 175 | break; |
140 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 176 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
141 | case ECRYPTFS_TRANSPORT_RELAYFS: | 177 | case ECRYPTFS_TRANSPORT_RELAYFS: |
142 | default: | 178 | default: |
143 | rc = -ENOSYS; | 179 | rc = -ENOSYS; |
144 | } | 180 | } |
181 | out: | ||
182 | return rc; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct | ||
187 | * @daemon: Pointer to set to newly allocated daemon struct | ||
188 | * @euid: Effective user id for the daemon | ||
189 | * @pid: Process id for the daemon | ||
190 | * | ||
191 | * Must be called ceremoniously while in possession of | ||
192 | * ecryptfs_sacred_daemon_hash_mux | ||
193 | * | ||
194 | * Returns zero on success; non-zero otherwise | ||
195 | */ | ||
196 | int | ||
197 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, pid_t pid) | ||
198 | { | ||
199 | int rc = 0; | ||
200 | |||
201 | (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL); | ||
202 | if (!(*daemon)) { | ||
203 | rc = -ENOMEM; | ||
204 | printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " | ||
205 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); | ||
206 | goto out; | ||
207 | } | ||
208 | (*daemon)->euid = euid; | ||
209 | (*daemon)->pid = pid; | ||
210 | (*daemon)->task = current; | ||
211 | mutex_init(&(*daemon)->mux); | ||
212 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); | ||
213 | init_waitqueue_head(&(*daemon)->wait); | ||
214 | (*daemon)->num_queued_msg_ctx = 0; | ||
215 | hlist_add_head(&(*daemon)->euid_chain, | ||
216 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]); | ||
217 | out: | ||
145 | return rc; | 218 | return rc; |
146 | } | 219 | } |
147 | 220 | ||
148 | /** | 221 | /** |
149 | * ecryptfs_process_helo | 222 | * ecryptfs_process_helo |
150 | * @transport: The underlying transport (netlink, etc.) | 223 | * @transport: The underlying transport (netlink, etc.) |
151 | * @uid: The user ID owner of the message | 224 | * @euid: The user ID owner of the message |
152 | * @pid: The process ID for the userspace program that sent the | 225 | * @pid: The process ID for the userspace program that sent the |
153 | * message | 226 | * message |
154 | * | 227 | * |
155 | * Adds the uid and pid values to the daemon id hash. If a uid | 228 | * Adds the euid and pid values to the daemon euid hash. If an euid |
156 | * already has a daemon pid registered, the daemon will be | 229 | * already has a daemon pid registered, the daemon will be |
157 | * unregistered before the new daemon id is put into the hash list. | 230 | * unregistered before the new daemon is put into the hash list. |
158 | * Returns zero after adding a new daemon id to the hash list; | 231 | * Returns zero after adding a new daemon to the hash list; |
159 | * non-zero otherwise. | 232 | * non-zero otherwise. |
160 | */ | 233 | */ |
161 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid) | 234 | int ecryptfs_process_helo(unsigned int transport, uid_t euid, pid_t pid) |
162 | { | 235 | { |
163 | struct ecryptfs_daemon_id *new_id; | 236 | struct ecryptfs_daemon *new_daemon; |
164 | struct ecryptfs_daemon_id *old_id; | 237 | struct ecryptfs_daemon *old_daemon; |
165 | int rc; | 238 | int rc; |
166 | 239 | ||
167 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 240 | mutex_lock(&ecryptfs_daemon_hash_mux); |
168 | new_id = kmalloc(sizeof(*new_id), GFP_KERNEL); | 241 | rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid); |
169 | if (!new_id) { | 242 | if (rc != 0) { |
170 | rc = -ENOMEM; | ||
171 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory; unable " | ||
172 | "to register daemon [%d] for user [%d]\n", | ||
173 | pid, uid); | ||
174 | goto unlock; | ||
175 | } | ||
176 | if (!ecryptfs_find_daemon_id(uid, &old_id)) { | ||
177 | printk(KERN_WARNING "Received request from user [%d] " | 243 | printk(KERN_WARNING "Received request from user [%d] " |
178 | "to register daemon [%d]; unregistering daemon " | 244 | "to register daemon [%d]; unregistering daemon " |
179 | "[%d]\n", uid, pid, old_id->pid); | 245 | "[%d]\n", euid, pid, old_daemon->pid); |
180 | hlist_del(&old_id->id_chain); | 246 | rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT, |
181 | rc = ecryptfs_send_raw_message(transport, ECRYPTFS_NLMSG_QUIT, | 247 | old_daemon); |
182 | old_id->pid); | ||
183 | if (rc) | 248 | if (rc) |
184 | printk(KERN_WARNING "Failed to send QUIT " | 249 | printk(KERN_WARNING "Failed to send QUIT " |
185 | "message to daemon [%d]; rc = [%d]\n", | 250 | "message to daemon [%d]; rc = [%d]\n", |
186 | old_id->pid, rc); | 251 | old_daemon->pid, rc); |
187 | kfree(old_id); | 252 | hlist_del(&old_daemon->euid_chain); |
253 | kfree(old_daemon); | ||
188 | } | 254 | } |
189 | new_id->uid = uid; | 255 | rc = ecryptfs_spawn_daemon(&new_daemon, euid, pid); |
190 | new_id->pid = pid; | 256 | if (rc) |
191 | hlist_add_head(&new_id->id_chain, | 257 | printk(KERN_ERR "%s: The gods are displeased with this attempt " |
192 | &ecryptfs_daemon_id_hash[ecryptfs_uid_hash(uid)]); | 258 | "to create a new daemon object for euid [%d]; pid [%d]; " |
193 | rc = 0; | 259 | "rc = [%d]\n", __func__, euid, pid, rc); |
194 | unlock: | 260 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
195 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 261 | return rc; |
262 | } | ||
263 | |||
264 | /** | ||
265 | * ecryptfs_exorcise_daemon - Destroy the daemon struct | ||
266 | * | ||
267 | * Must be called ceremoniously while in possession of | ||
268 | * ecryptfs_daemon_hash_mux and the daemon's own mux. | ||
269 | */ | ||
270 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | ||
271 | { | ||
272 | struct ecryptfs_msg_ctx *msg_ctx, *msg_ctx_tmp; | ||
273 | int rc = 0; | ||
274 | |||
275 | mutex_lock(&daemon->mux); | ||
276 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) | ||
277 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { | ||
278 | rc = -EBUSY; | ||
279 | printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " | ||
280 | "[%d], but it is in the midst of a read or a poll\n", | ||
281 | __func__, daemon->pid); | ||
282 | mutex_unlock(&daemon->mux); | ||
283 | goto out; | ||
284 | } | ||
285 | list_for_each_entry_safe(msg_ctx, msg_ctx_tmp, | ||
286 | &daemon->msg_ctx_out_queue, daemon_out_list) { | ||
287 | list_del(&msg_ctx->daemon_out_list); | ||
288 | daemon->num_queued_msg_ctx--; | ||
289 | printk(KERN_WARNING "%s: Warning: dropping message that is in " | ||
290 | "the out queue of a dying daemon\n", __func__); | ||
291 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); | ||
292 | } | ||
293 | hlist_del(&daemon->euid_chain); | ||
294 | if (daemon->task) | ||
295 | wake_up_process(daemon->task); | ||
296 | mutex_unlock(&daemon->mux); | ||
297 | memset(daemon, 0, sizeof(*daemon)); | ||
298 | kfree(daemon); | ||
299 | out: | ||
196 | return rc; | 300 | return rc; |
197 | } | 301 | } |
198 | 302 | ||
199 | /** | 303 | /** |
200 | * ecryptfs_process_quit | 304 | * ecryptfs_process_quit |
201 | * @uid: The user ID owner of the message | 305 | * @euid: The user ID owner of the message |
202 | * @pid: The process ID for the userspace program that sent the | 306 | * @pid: The process ID for the userspace program that sent the |
203 | * message | 307 | * message |
204 | * | 308 | * |
205 | * Deletes the corresponding daemon id for the given uid and pid, if | 309 | * Deletes the corresponding daemon for the given euid and pid, if |
206 | * it is the registered that is requesting the deletion. Returns zero | 310 | * it is the registered that is requesting the deletion. Returns zero |
207 | * after deleting the desired daemon id; non-zero otherwise. | 311 | * after deleting the desired daemon; non-zero otherwise. |
208 | */ | 312 | */ |
209 | int ecryptfs_process_quit(uid_t uid, pid_t pid) | 313 | int ecryptfs_process_quit(uid_t euid, pid_t pid) |
210 | { | 314 | { |
211 | struct ecryptfs_daemon_id *id; | 315 | struct ecryptfs_daemon *daemon; |
212 | int rc; | 316 | int rc; |
213 | 317 | ||
214 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 318 | mutex_lock(&ecryptfs_daemon_hash_mux); |
215 | if (ecryptfs_find_daemon_id(uid, &id)) { | 319 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid); |
216 | rc = -EINVAL; | 320 | if (rc || !daemon) { |
217 | ecryptfs_printk(KERN_ERR, "Received request from user [%d] to " | ||
218 | "unregister unrecognized daemon [%d]\n", uid, | ||
219 | pid); | ||
220 | goto unlock; | ||
221 | } | ||
222 | if (id->pid != pid) { | ||
223 | rc = -EINVAL; | 321 | rc = -EINVAL; |
224 | ecryptfs_printk(KERN_WARNING, "Received request from user [%d] " | 322 | printk(KERN_ERR "Received request from user [%d] to " |
225 | "with pid [%d] to unregister daemon [%d]\n", | 323 | "unregister unrecognized daemon [%d]\n", euid, pid); |
226 | uid, pid, id->pid); | 324 | goto out_unlock; |
227 | goto unlock; | ||
228 | } | 325 | } |
229 | hlist_del(&id->id_chain); | 326 | rc = ecryptfs_exorcise_daemon(daemon); |
230 | kfree(id); | 327 | out_unlock: |
231 | rc = 0; | 328 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
232 | unlock: | ||
233 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
234 | return rc; | 329 | return rc; |
235 | } | 330 | } |
236 | 331 | ||
237 | /** | 332 | /** |
238 | * ecryptfs_process_reponse | 333 | * ecryptfs_process_reponse |
239 | * @msg: The ecryptfs message received; the caller should sanity check | 334 | * @msg: The ecryptfs message received; the caller should sanity check |
240 | * msg->data_len | 335 | * msg->data_len and free the memory |
241 | * @pid: The process ID of the userspace application that sent the | 336 | * @pid: The process ID of the userspace application that sent the |
242 | * message | 337 | * message |
243 | * @seq: The sequence number of the message | 338 | * @seq: The sequence number of the message; must match the sequence |
339 | * number for the existing message context waiting for this | ||
340 | * response | ||
341 | * | ||
342 | * Processes a response message after sending an operation request to | ||
343 | * userspace. Some other process is awaiting this response. Before | ||
344 | * sending out its first communications, the other process allocated a | ||
345 | * msg_ctx from the ecryptfs_msg_ctx_arr at a particular index. The | ||
346 | * response message contains this index so that we can copy over the | ||
347 | * response message into the msg_ctx that the process holds a | ||
348 | * reference to. The other process is going to wake up, check to see | ||
349 | * that msg_ctx->state == ECRYPTFS_MSG_CTX_STATE_DONE, and then | ||
350 | * proceed to read off and process the response message. Returns zero | ||
351 | * upon delivery to desired context element; non-zero upon delivery | ||
352 | * failure or error. | ||
244 | * | 353 | * |
245 | * Processes a response message after sending a operation request to | 354 | * Returns zero on success; non-zero otherwise |
246 | * userspace. Returns zero upon delivery to desired context element; | ||
247 | * non-zero upon delivery failure or error. | ||
248 | */ | 355 | */ |
249 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | 356 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, |
250 | pid_t pid, u32 seq) | 357 | pid_t pid, u32 seq) |
251 | { | 358 | { |
252 | struct ecryptfs_daemon_id *id; | 359 | struct ecryptfs_daemon *daemon; |
253 | struct ecryptfs_msg_ctx *msg_ctx; | 360 | struct ecryptfs_msg_ctx *msg_ctx; |
254 | int msg_size; | 361 | size_t msg_size; |
255 | int rc; | 362 | int rc; |
256 | 363 | ||
257 | if (msg->index >= ecryptfs_message_buf_len) { | 364 | if (msg->index >= ecryptfs_message_buf_len) { |
258 | rc = -EINVAL; | 365 | rc = -EINVAL; |
259 | ecryptfs_printk(KERN_ERR, "Attempt to reference " | 366 | printk(KERN_ERR "%s: Attempt to reference " |
260 | "context buffer at index [%d]; maximum " | 367 | "context buffer at index [%d]; maximum " |
261 | "allowable is [%d]\n", msg->index, | 368 | "allowable is [%d]\n", __func__, msg->index, |
262 | (ecryptfs_message_buf_len - 1)); | 369 | (ecryptfs_message_buf_len - 1)); |
263 | goto out; | 370 | goto out; |
264 | } | 371 | } |
265 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; | 372 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; |
266 | mutex_lock(&msg_ctx->mux); | 373 | mutex_lock(&msg_ctx->mux); |
267 | if (ecryptfs_find_daemon_id(msg_ctx->task->euid, &id)) { | 374 | mutex_lock(&ecryptfs_daemon_hash_mux); |
375 | rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid); | ||
376 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
377 | if (rc) { | ||
268 | rc = -EBADMSG; | 378 | rc = -EBADMSG; |
269 | ecryptfs_printk(KERN_WARNING, "User [%d] received a " | 379 | printk(KERN_WARNING "%s: User [%d] received a " |
270 | "message response from process [%d] but does " | 380 | "message response from process [%d] but does " |
271 | "not have a registered daemon\n", | 381 | "not have a registered daemon\n", __func__, |
272 | msg_ctx->task->euid, pid); | 382 | msg_ctx->task->euid, pid); |
273 | goto wake_up; | 383 | goto wake_up; |
274 | } | 384 | } |
275 | if (msg_ctx->task->euid != uid) { | 385 | if (msg_ctx->task->euid != euid) { |
276 | rc = -EBADMSG; | 386 | rc = -EBADMSG; |
277 | ecryptfs_printk(KERN_WARNING, "Received message from user " | 387 | printk(KERN_WARNING "%s: Received message from user " |
278 | "[%d]; expected message from user [%d]\n", | 388 | "[%d]; expected message from user [%d]\n", __func__, |
279 | uid, msg_ctx->task->euid); | 389 | euid, msg_ctx->task->euid); |
280 | goto unlock; | 390 | goto unlock; |
281 | } | 391 | } |
282 | if (id->pid != pid) { | 392 | if (daemon->pid != pid) { |
283 | rc = -EBADMSG; | 393 | rc = -EBADMSG; |
284 | ecryptfs_printk(KERN_ERR, "User [%d] received a " | 394 | printk(KERN_ERR "%s: User [%d] sent a message response " |
285 | "message response from an unrecognized " | 395 | "from an unrecognized process [%d]\n", |
286 | "process [%d]\n", msg_ctx->task->euid, pid); | 396 | __func__, msg_ctx->task->euid, pid); |
287 | goto unlock; | 397 | goto unlock; |
288 | } | 398 | } |
289 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { | 399 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { |
290 | rc = -EINVAL; | 400 | rc = -EINVAL; |
291 | ecryptfs_printk(KERN_WARNING, "Desired context element is not " | 401 | printk(KERN_WARNING "%s: Desired context element is not " |
292 | "pending a response\n"); | 402 | "pending a response\n", __func__); |
293 | goto unlock; | 403 | goto unlock; |
294 | } else if (msg_ctx->counter != seq) { | 404 | } else if (msg_ctx->counter != seq) { |
295 | rc = -EINVAL; | 405 | rc = -EINVAL; |
296 | ecryptfs_printk(KERN_WARNING, "Invalid message sequence; " | 406 | printk(KERN_WARNING "%s: Invalid message sequence; " |
297 | "expected [%d]; received [%d]\n", | 407 | "expected [%d]; received [%d]\n", __func__, |
298 | msg_ctx->counter, seq); | 408 | msg_ctx->counter, seq); |
299 | goto unlock; | 409 | goto unlock; |
300 | } | 410 | } |
301 | msg_size = sizeof(*msg) + msg->data_len; | 411 | msg_size = (sizeof(*msg) + msg->data_len); |
302 | msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); | 412 | msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); |
303 | if (!msg_ctx->msg) { | 413 | if (!msg_ctx->msg) { |
304 | rc = -ENOMEM; | 414 | rc = -ENOMEM; |
305 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | 415 | printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " |
416 | "GFP_KERNEL memory\n", __func__, msg_size); | ||
306 | goto unlock; | 417 | goto unlock; |
307 | } | 418 | } |
308 | memcpy(msg_ctx->msg, msg, msg_size); | 419 | memcpy(msg_ctx->msg, msg, msg_size); |
@@ -317,34 +428,37 @@ out: | |||
317 | } | 428 | } |
318 | 429 | ||
319 | /** | 430 | /** |
320 | * ecryptfs_send_message | 431 | * ecryptfs_send_message_locked |
321 | * @transport: The transport over which to send the message (i.e., | 432 | * @transport: The transport over which to send the message (i.e., |
322 | * netlink) | 433 | * netlink) |
323 | * @data: The data to send | 434 | * @data: The data to send |
324 | * @data_len: The length of data | 435 | * @data_len: The length of data |
325 | * @msg_ctx: The message context allocated for the send | 436 | * @msg_ctx: The message context allocated for the send |
437 | * | ||
438 | * Must be called with ecryptfs_daemon_hash_mux held. | ||
439 | * | ||
440 | * Returns zero on success; non-zero otherwise | ||
326 | */ | 441 | */ |
327 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | 442 | static int |
328 | struct ecryptfs_msg_ctx **msg_ctx) | 443 | ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len, |
444 | u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx) | ||
329 | { | 445 | { |
330 | struct ecryptfs_daemon_id *id; | 446 | struct ecryptfs_daemon *daemon; |
331 | int rc; | 447 | int rc; |
332 | 448 | ||
333 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 449 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid); |
334 | if (ecryptfs_find_daemon_id(current->euid, &id)) { | 450 | if (rc || !daemon) { |
335 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
336 | rc = -ENOTCONN; | 451 | rc = -ENOTCONN; |
337 | ecryptfs_printk(KERN_ERR, "User [%d] does not have a daemon " | 452 | printk(KERN_ERR "%s: User [%d] does not have a daemon " |
338 | "registered\n", current->euid); | 453 | "registered\n", __func__, current->euid); |
339 | goto out; | 454 | goto out; |
340 | } | 455 | } |
341 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
342 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | 456 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); |
343 | rc = ecryptfs_acquire_free_msg_ctx(msg_ctx); | 457 | rc = ecryptfs_acquire_free_msg_ctx(msg_ctx); |
344 | if (rc) { | 458 | if (rc) { |
345 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | 459 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); |
346 | ecryptfs_printk(KERN_WARNING, "Could not claim a free " | 460 | printk(KERN_WARNING "%s: Could not claim a free " |
347 | "context element\n"); | 461 | "context element\n", __func__); |
348 | goto out; | 462 | goto out; |
349 | } | 463 | } |
350 | ecryptfs_msg_ctx_free_to_alloc(*msg_ctx); | 464 | ecryptfs_msg_ctx_free_to_alloc(*msg_ctx); |
@@ -352,23 +466,50 @@ int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | |||
352 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | 466 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); |
353 | switch (transport) { | 467 | switch (transport) { |
354 | case ECRYPTFS_TRANSPORT_NETLINK: | 468 | case ECRYPTFS_TRANSPORT_NETLINK: |
355 | rc = ecryptfs_send_netlink(data, data_len, *msg_ctx, | 469 | rc = ecryptfs_send_netlink(data, data_len, *msg_ctx, msg_type, |
356 | ECRYPTFS_NLMSG_REQUEST, 0, id->pid); | 470 | 0, daemon->pid); |
471 | break; | ||
472 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
473 | rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type, | ||
474 | 0, daemon); | ||
357 | break; | 475 | break; |
358 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 476 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
359 | case ECRYPTFS_TRANSPORT_RELAYFS: | 477 | case ECRYPTFS_TRANSPORT_RELAYFS: |
360 | default: | 478 | default: |
361 | rc = -ENOSYS; | 479 | rc = -ENOSYS; |
362 | } | 480 | } |
363 | if (rc) { | 481 | if (rc) |
364 | printk(KERN_ERR "Error attempting to send message to userspace " | 482 | printk(KERN_ERR "%s: Error attempting to send message to " |
365 | "daemon; rc = [%d]\n", rc); | 483 | "userspace daemon; rc = [%d]\n", __func__, rc); |
366 | } | ||
367 | out: | 484 | out: |
368 | return rc; | 485 | return rc; |
369 | } | 486 | } |
370 | 487 | ||
371 | /** | 488 | /** |
489 | * ecryptfs_send_message | ||
490 | * @transport: The transport over which to send the message (i.e., | ||
491 | * netlink) | ||
492 | * @data: The data to send | ||
493 | * @data_len: The length of data | ||
494 | * @msg_ctx: The message context allocated for the send | ||
495 | * | ||
496 | * Grabs ecryptfs_daemon_hash_mux. | ||
497 | * | ||
498 | * Returns zero on success; non-zero otherwise | ||
499 | */ | ||
500 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | ||
501 | struct ecryptfs_msg_ctx **msg_ctx) | ||
502 | { | ||
503 | int rc; | ||
504 | |||
505 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
506 | rc = ecryptfs_send_message_locked(transport, data, data_len, | ||
507 | ECRYPTFS_MSG_REQUEST, msg_ctx); | ||
508 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
509 | return rc; | ||
510 | } | ||
511 | |||
512 | /** | ||
372 | * ecryptfs_wait_for_response | 513 | * ecryptfs_wait_for_response |
373 | * @msg_ctx: The context that was assigned when sending a message | 514 | * @msg_ctx: The context that was assigned when sending a message |
374 | * @msg: The incoming message from userspace; not set if rc != 0 | 515 | * @msg: The incoming message from userspace; not set if rc != 0 |
@@ -377,7 +518,7 @@ out: | |||
377 | * of time exceeds ecryptfs_message_wait_timeout. If zero is | 518 | * of time exceeds ecryptfs_message_wait_timeout. If zero is |
378 | * returned, msg will point to a valid message from userspace; a | 519 | * returned, msg will point to a valid message from userspace; a |
379 | * non-zero value is returned upon failure to receive a message or an | 520 | * non-zero value is returned upon failure to receive a message or an |
380 | * error occurs. | 521 | * error occurs. Callee must free @msg on success. |
381 | */ | 522 | */ |
382 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | 523 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, |
383 | struct ecryptfs_message **msg) | 524 | struct ecryptfs_message **msg) |
@@ -413,32 +554,32 @@ int ecryptfs_init_messaging(unsigned int transport) | |||
413 | 554 | ||
414 | if (ecryptfs_number_of_users > ECRYPTFS_MAX_NUM_USERS) { | 555 | if (ecryptfs_number_of_users > ECRYPTFS_MAX_NUM_USERS) { |
415 | ecryptfs_number_of_users = ECRYPTFS_MAX_NUM_USERS; | 556 | ecryptfs_number_of_users = ECRYPTFS_MAX_NUM_USERS; |
416 | ecryptfs_printk(KERN_WARNING, "Specified number of users is " | 557 | printk(KERN_WARNING "%s: Specified number of users is " |
417 | "too large, defaulting to [%d] users\n", | 558 | "too large, defaulting to [%d] users\n", __func__, |
418 | ecryptfs_number_of_users); | 559 | ecryptfs_number_of_users); |
419 | } | 560 | } |
420 | mutex_init(&ecryptfs_daemon_id_hash_mux); | 561 | mutex_init(&ecryptfs_daemon_hash_mux); |
421 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 562 | mutex_lock(&ecryptfs_daemon_hash_mux); |
422 | ecryptfs_hash_buckets = 1; | 563 | ecryptfs_hash_buckets = 1; |
423 | while (ecryptfs_number_of_users >> ecryptfs_hash_buckets) | 564 | while (ecryptfs_number_of_users >> ecryptfs_hash_buckets) |
424 | ecryptfs_hash_buckets++; | 565 | ecryptfs_hash_buckets++; |
425 | ecryptfs_daemon_id_hash = kmalloc(sizeof(struct hlist_head) | 566 | ecryptfs_daemon_hash = kmalloc((sizeof(struct hlist_head) |
426 | * ecryptfs_hash_buckets, GFP_KERNEL); | 567 | * ecryptfs_hash_buckets), GFP_KERNEL); |
427 | if (!ecryptfs_daemon_id_hash) { | 568 | if (!ecryptfs_daemon_hash) { |
428 | rc = -ENOMEM; | 569 | rc = -ENOMEM; |
429 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | 570 | printk(KERN_ERR "%s: Failed to allocate memory\n", __func__); |
430 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 571 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
431 | goto out; | 572 | goto out; |
432 | } | 573 | } |
433 | for (i = 0; i < ecryptfs_hash_buckets; i++) | 574 | for (i = 0; i < ecryptfs_hash_buckets; i++) |
434 | INIT_HLIST_HEAD(&ecryptfs_daemon_id_hash[i]); | 575 | INIT_HLIST_HEAD(&ecryptfs_daemon_hash[i]); |
435 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 576 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
436 | |||
437 | ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx) | 577 | ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx) |
438 | * ecryptfs_message_buf_len), GFP_KERNEL); | 578 | * ecryptfs_message_buf_len), |
579 | GFP_KERNEL); | ||
439 | if (!ecryptfs_msg_ctx_arr) { | 580 | if (!ecryptfs_msg_ctx_arr) { |
440 | rc = -ENOMEM; | 581 | rc = -ENOMEM; |
441 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | 582 | printk(KERN_ERR "%s: Failed to allocate memory\n", __func__); |
442 | goto out; | 583 | goto out; |
443 | } | 584 | } |
444 | mutex_init(&ecryptfs_msg_ctx_lists_mux); | 585 | mutex_init(&ecryptfs_msg_ctx_lists_mux); |
@@ -446,6 +587,7 @@ int ecryptfs_init_messaging(unsigned int transport) | |||
446 | ecryptfs_msg_counter = 0; | 587 | ecryptfs_msg_counter = 0; |
447 | for (i = 0; i < ecryptfs_message_buf_len; i++) { | 588 | for (i = 0; i < ecryptfs_message_buf_len; i++) { |
448 | INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].node); | 589 | INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].node); |
590 | INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].daemon_out_list); | ||
449 | mutex_init(&ecryptfs_msg_ctx_arr[i].mux); | 591 | mutex_init(&ecryptfs_msg_ctx_arr[i].mux); |
450 | mutex_lock(&ecryptfs_msg_ctx_arr[i].mux); | 592 | mutex_lock(&ecryptfs_msg_ctx_arr[i].mux); |
451 | ecryptfs_msg_ctx_arr[i].index = i; | 593 | ecryptfs_msg_ctx_arr[i].index = i; |
@@ -464,6 +606,11 @@ int ecryptfs_init_messaging(unsigned int transport) | |||
464 | if (rc) | 606 | if (rc) |
465 | ecryptfs_release_messaging(transport); | 607 | ecryptfs_release_messaging(transport); |
466 | break; | 608 | break; |
609 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
610 | rc = ecryptfs_init_ecryptfs_miscdev(); | ||
611 | if (rc) | ||
612 | ecryptfs_release_messaging(transport); | ||
613 | break; | ||
467 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 614 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
468 | case ECRYPTFS_TRANSPORT_RELAYFS: | 615 | case ECRYPTFS_TRANSPORT_RELAYFS: |
469 | default: | 616 | default: |
@@ -488,27 +635,37 @@ void ecryptfs_release_messaging(unsigned int transport) | |||
488 | kfree(ecryptfs_msg_ctx_arr); | 635 | kfree(ecryptfs_msg_ctx_arr); |
489 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | 636 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); |
490 | } | 637 | } |
491 | if (ecryptfs_daemon_id_hash) { | 638 | if (ecryptfs_daemon_hash) { |
492 | struct hlist_node *elem; | 639 | struct hlist_node *elem; |
493 | struct ecryptfs_daemon_id *id; | 640 | struct ecryptfs_daemon *daemon; |
494 | int i; | 641 | int i; |
495 | 642 | ||
496 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 643 | mutex_lock(&ecryptfs_daemon_hash_mux); |
497 | for (i = 0; i < ecryptfs_hash_buckets; i++) { | 644 | for (i = 0; i < ecryptfs_hash_buckets; i++) { |
498 | hlist_for_each_entry(id, elem, | 645 | int rc; |
499 | &ecryptfs_daemon_id_hash[i], | 646 | |
500 | id_chain) { | 647 | hlist_for_each_entry(daemon, elem, |
501 | hlist_del(elem); | 648 | &ecryptfs_daemon_hash[i], |
502 | kfree(id); | 649 | euid_chain) { |
650 | rc = ecryptfs_exorcise_daemon(daemon); | ||
651 | if (rc) | ||
652 | printk(KERN_ERR "%s: Error whilst " | ||
653 | "attempting to destroy daemon; " | ||
654 | "rc = [%d]. Dazed and confused, " | ||
655 | "but trying to continue.\n", | ||
656 | __func__, rc); | ||
503 | } | 657 | } |
504 | } | 658 | } |
505 | kfree(ecryptfs_daemon_id_hash); | 659 | kfree(ecryptfs_daemon_hash); |
506 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 660 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
507 | } | 661 | } |
508 | switch(transport) { | 662 | switch(transport) { |
509 | case ECRYPTFS_TRANSPORT_NETLINK: | 663 | case ECRYPTFS_TRANSPORT_NETLINK: |
510 | ecryptfs_release_netlink(); | 664 | ecryptfs_release_netlink(); |
511 | break; | 665 | break; |
666 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
667 | ecryptfs_destroy_ecryptfs_miscdev(); | ||
668 | break; | ||
512 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 669 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
513 | case ECRYPTFS_TRANSPORT_RELAYFS: | 670 | case ECRYPTFS_TRANSPORT_RELAYFS: |
514 | default: | 671 | default: |