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