diff options
Diffstat (limited to 'fs/ecryptfs/messaging.c')
-rw-r--r-- | fs/ecryptfs/messaging.c | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index c6038bd60897..1b5c20058acb 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -20,6 +20,8 @@ | |||
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); |
@@ -103,6 +105,7 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | |||
103 | /** | 105 | /** |
104 | * ecryptfs_find_daemon_by_euid | 106 | * ecryptfs_find_daemon_by_euid |
105 | * @euid: The effective user id which maps to the desired daemon id | 107 | * @euid: The effective user id which maps to the desired daemon id |
108 | * @user_ns: The namespace in which @euid applies | ||
106 | * @daemon: If return value is zero, points to the desired daemon pointer | 109 | * @daemon: If return value is zero, points to the desired daemon pointer |
107 | * | 110 | * |
108 | * Must be called with ecryptfs_daemon_hash_mux held. | 111 | * Must be called with ecryptfs_daemon_hash_mux held. |
@@ -111,7 +114,8 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | |||
111 | * | 114 | * |
112 | * Returns zero if the user id exists in the list; non-zero otherwise. | 115 | * Returns zero if the user id exists in the list; non-zero otherwise. |
113 | */ | 116 | */ |
114 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid) | 117 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, |
118 | struct user_namespace *user_ns) | ||
115 | { | 119 | { |
116 | struct hlist_node *elem; | 120 | struct hlist_node *elem; |
117 | int rc; | 121 | int rc; |
@@ -119,7 +123,7 @@ int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid) | |||
119 | hlist_for_each_entry(*daemon, elem, | 123 | hlist_for_each_entry(*daemon, elem, |
120 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], | 124 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], |
121 | euid_chain) { | 125 | euid_chain) { |
122 | if ((*daemon)->euid == euid) { | 126 | if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) { |
123 | rc = 0; | 127 | rc = 0; |
124 | goto out; | 128 | goto out; |
125 | } | 129 | } |
@@ -186,6 +190,7 @@ out: | |||
186 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct | 190 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct |
187 | * @daemon: Pointer to set to newly allocated daemon struct | 191 | * @daemon: Pointer to set to newly allocated daemon struct |
188 | * @euid: Effective user id for the daemon | 192 | * @euid: Effective user id for the daemon |
193 | * @user_ns: The namespace in which @euid applies | ||
189 | * @pid: Process id for the daemon | 194 | * @pid: Process id for the daemon |
190 | * | 195 | * |
191 | * Must be called ceremoniously while in possession of | 196 | * Must be called ceremoniously while in possession of |
@@ -194,7 +199,8 @@ out: | |||
194 | * Returns zero on success; non-zero otherwise | 199 | * Returns zero on success; non-zero otherwise |
195 | */ | 200 | */ |
196 | int | 201 | int |
197 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, pid_t pid) | 202 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, |
203 | struct user_namespace *user_ns, struct pid *pid) | ||
198 | { | 204 | { |
199 | int rc = 0; | 205 | int rc = 0; |
200 | 206 | ||
@@ -206,7 +212,8 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, pid_t pid) | |||
206 | goto out; | 212 | goto out; |
207 | } | 213 | } |
208 | (*daemon)->euid = euid; | 214 | (*daemon)->euid = euid; |
209 | (*daemon)->pid = pid; | 215 | (*daemon)->user_ns = get_user_ns(user_ns); |
216 | (*daemon)->pid = get_pid(pid); | ||
210 | (*daemon)->task = current; | 217 | (*daemon)->task = current; |
211 | mutex_init(&(*daemon)->mux); | 218 | mutex_init(&(*daemon)->mux); |
212 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); | 219 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); |
@@ -222,6 +229,7 @@ out: | |||
222 | * ecryptfs_process_helo | 229 | * ecryptfs_process_helo |
223 | * @transport: The underlying transport (netlink, etc.) | 230 | * @transport: The underlying transport (netlink, etc.) |
224 | * @euid: 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 | ||
225 | * @pid: The process ID for the userspace program that sent the | 233 | * @pid: The process ID for the userspace program that sent the |
226 | * message | 234 | * message |
227 | * | 235 | * |
@@ -231,32 +239,33 @@ out: | |||
231 | * Returns zero after adding a new daemon to the hash list; | 239 | * Returns zero after adding a new daemon to the hash list; |
232 | * non-zero otherwise. | 240 | * non-zero otherwise. |
233 | */ | 241 | */ |
234 | int ecryptfs_process_helo(unsigned int transport, uid_t euid, pid_t pid) | 242 | int ecryptfs_process_helo(unsigned int transport, uid_t euid, |
243 | struct user_namespace *user_ns, struct pid *pid) | ||
235 | { | 244 | { |
236 | struct ecryptfs_daemon *new_daemon; | 245 | struct ecryptfs_daemon *new_daemon; |
237 | struct ecryptfs_daemon *old_daemon; | 246 | struct ecryptfs_daemon *old_daemon; |
238 | int rc; | 247 | int rc; |
239 | 248 | ||
240 | mutex_lock(&ecryptfs_daemon_hash_mux); | 249 | mutex_lock(&ecryptfs_daemon_hash_mux); |
241 | rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid); | 250 | rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid, user_ns); |
242 | if (rc != 0) { | 251 | if (rc != 0) { |
243 | printk(KERN_WARNING "Received request from user [%d] " | 252 | printk(KERN_WARNING "Received request from user [%d] " |
244 | "to register daemon [%d]; unregistering daemon " | 253 | "to register daemon [0x%p]; unregistering daemon " |
245 | "[%d]\n", euid, pid, old_daemon->pid); | 254 | "[0x%p]\n", euid, pid, old_daemon->pid); |
246 | rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT, | 255 | rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT, |
247 | old_daemon); | 256 | old_daemon); |
248 | if (rc) | 257 | if (rc) |
249 | printk(KERN_WARNING "Failed to send QUIT " | 258 | printk(KERN_WARNING "Failed to send QUIT " |
250 | "message to daemon [%d]; rc = [%d]\n", | 259 | "message to daemon [0x%p]; rc = [%d]\n", |
251 | old_daemon->pid, rc); | 260 | old_daemon->pid, rc); |
252 | hlist_del(&old_daemon->euid_chain); | 261 | hlist_del(&old_daemon->euid_chain); |
253 | kfree(old_daemon); | 262 | kfree(old_daemon); |
254 | } | 263 | } |
255 | rc = ecryptfs_spawn_daemon(&new_daemon, euid, pid); | 264 | rc = ecryptfs_spawn_daemon(&new_daemon, euid, user_ns, pid); |
256 | if (rc) | 265 | if (rc) |
257 | printk(KERN_ERR "%s: The gods are displeased with this attempt " | 266 | printk(KERN_ERR "%s: The gods are displeased with this attempt " |
258 | "to create a new daemon object for euid [%d]; pid [%d]; " | 267 | "to create a new daemon object for euid [%d]; pid " |
259 | "rc = [%d]\n", __func__, euid, pid, rc); | 268 | "[0x%p]; rc = [%d]\n", __func__, euid, pid, rc); |
260 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 269 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
261 | return rc; | 270 | return rc; |
262 | } | 271 | } |
@@ -277,7 +286,7 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
277 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { | 286 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { |
278 | rc = -EBUSY; | 287 | rc = -EBUSY; |
279 | printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " | 288 | 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", | 289 | "[0x%p], but it is in the midst of a read or a poll\n", |
281 | __func__, daemon->pid); | 290 | __func__, daemon->pid); |
282 | mutex_unlock(&daemon->mux); | 291 | mutex_unlock(&daemon->mux); |
283 | goto out; | 292 | goto out; |
@@ -293,6 +302,10 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
293 | hlist_del(&daemon->euid_chain); | 302 | hlist_del(&daemon->euid_chain); |
294 | if (daemon->task) | 303 | if (daemon->task) |
295 | wake_up_process(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); | ||
296 | mutex_unlock(&daemon->mux); | 309 | mutex_unlock(&daemon->mux); |
297 | memset(daemon, 0, sizeof(*daemon)); | 310 | memset(daemon, 0, sizeof(*daemon)); |
298 | kfree(daemon); | 311 | kfree(daemon); |
@@ -303,6 +316,7 @@ out: | |||
303 | /** | 316 | /** |
304 | * ecryptfs_process_quit | 317 | * ecryptfs_process_quit |
305 | * @euid: 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 | ||
306 | * @pid: The process ID for the userspace program that sent the | 320 | * @pid: The process ID for the userspace program that sent the |
307 | * message | 321 | * message |
308 | * | 322 | * |
@@ -310,17 +324,18 @@ out: | |||
310 | * it is the registered that is requesting the deletion. Returns zero | 324 | * it is the registered that is requesting the deletion. Returns zero |
311 | * after deleting the desired daemon; non-zero otherwise. | 325 | * after deleting the desired daemon; non-zero otherwise. |
312 | */ | 326 | */ |
313 | int ecryptfs_process_quit(uid_t euid, pid_t pid) | 327 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, |
328 | struct pid *pid) | ||
314 | { | 329 | { |
315 | struct ecryptfs_daemon *daemon; | 330 | struct ecryptfs_daemon *daemon; |
316 | int rc; | 331 | int rc; |
317 | 332 | ||
318 | mutex_lock(&ecryptfs_daemon_hash_mux); | 333 | mutex_lock(&ecryptfs_daemon_hash_mux); |
319 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid); | 334 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, user_ns); |
320 | if (rc || !daemon) { | 335 | if (rc || !daemon) { |
321 | rc = -EINVAL; | 336 | rc = -EINVAL; |
322 | printk(KERN_ERR "Received request from user [%d] to " | 337 | printk(KERN_ERR "Received request from user [%d] to " |
323 | "unregister unrecognized daemon [%d]\n", euid, pid); | 338 | "unregister unrecognized daemon [0x%p]\n", euid, pid); |
324 | goto out_unlock; | 339 | goto out_unlock; |
325 | } | 340 | } |
326 | rc = ecryptfs_exorcise_daemon(daemon); | 341 | rc = ecryptfs_exorcise_daemon(daemon); |
@@ -354,11 +369,14 @@ out_unlock: | |||
354 | * Returns zero on success; non-zero otherwise | 369 | * Returns zero on success; non-zero otherwise |
355 | */ | 370 | */ |
356 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | 371 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, |
357 | pid_t pid, u32 seq) | 372 | struct user_namespace *user_ns, struct pid *pid, |
373 | u32 seq) | ||
358 | { | 374 | { |
359 | struct ecryptfs_daemon *daemon; | 375 | struct ecryptfs_daemon *daemon; |
360 | struct ecryptfs_msg_ctx *msg_ctx; | 376 | struct ecryptfs_msg_ctx *msg_ctx; |
361 | size_t msg_size; | 377 | size_t msg_size; |
378 | struct nsproxy *nsproxy; | ||
379 | struct user_namespace *current_user_ns; | ||
362 | int rc; | 380 | int rc; |
363 | 381 | ||
364 | if (msg->index >= ecryptfs_message_buf_len) { | 382 | if (msg->index >= ecryptfs_message_buf_len) { |
@@ -372,12 +390,25 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
372 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; | 390 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; |
373 | mutex_lock(&msg_ctx->mux); | 391 | mutex_lock(&msg_ctx->mux); |
374 | mutex_lock(&ecryptfs_daemon_hash_mux); | 392 | mutex_lock(&ecryptfs_daemon_hash_mux); |
375 | rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid); | 393 | rcu_read_lock(); |
394 | nsproxy = task_nsproxy(msg_ctx->task); | ||
395 | if (nsproxy == NULL) { | ||
396 | rc = -EBADMSG; | ||
397 | printk(KERN_ERR "%s: Receiving process is a zombie. Dropping " | ||
398 | "message.\n", __func__); | ||
399 | rcu_read_unlock(); | ||
400 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
401 | goto wake_up; | ||
402 | } | ||
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(); | ||
376 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 407 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
377 | if (rc) { | 408 | if (rc) { |
378 | rc = -EBADMSG; | 409 | rc = -EBADMSG; |
379 | printk(KERN_WARNING "%s: User [%d] received a " | 410 | printk(KERN_WARNING "%s: User [%d] received a " |
380 | "message response from process [%d] but does " | 411 | "message response from process [0x%p] but does " |
381 | "not have a registered daemon\n", __func__, | 412 | "not have a registered daemon\n", __func__, |
382 | msg_ctx->task->euid, pid); | 413 | msg_ctx->task->euid, pid); |
383 | goto wake_up; | 414 | goto wake_up; |
@@ -389,10 +420,17 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
389 | euid, msg_ctx->task->euid); | 420 | euid, msg_ctx->task->euid); |
390 | goto unlock; | 421 | goto unlock; |
391 | } | 422 | } |
423 | if (current_user_ns != user_ns) { | ||
424 | rc = -EBADMSG; | ||
425 | printk(KERN_WARNING "%s: Received message from user_ns " | ||
426 | "[0x%p]; expected message from user_ns [0x%p]\n", | ||
427 | __func__, user_ns, nsproxy->user_ns); | ||
428 | goto unlock; | ||
429 | } | ||
392 | if (daemon->pid != pid) { | 430 | if (daemon->pid != pid) { |
393 | rc = -EBADMSG; | 431 | rc = -EBADMSG; |
394 | printk(KERN_ERR "%s: User [%d] sent a message response " | 432 | printk(KERN_ERR "%s: User [%d] sent a message response " |
395 | "from an unrecognized process [%d]\n", | 433 | "from an unrecognized process [0x%p]\n", |
396 | __func__, msg_ctx->task->euid, pid); | 434 | __func__, msg_ctx->task->euid, pid); |
397 | goto unlock; | 435 | goto unlock; |
398 | } | 436 | } |
@@ -446,7 +484,8 @@ ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len, | |||
446 | struct ecryptfs_daemon *daemon; | 484 | struct ecryptfs_daemon *daemon; |
447 | int rc; | 485 | int rc; |
448 | 486 | ||
449 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid); | 487 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, |
488 | current->nsproxy->user_ns); | ||
450 | if (rc || !daemon) { | 489 | if (rc || !daemon) { |
451 | rc = -ENOTCONN; | 490 | rc = -ENOTCONN; |
452 | printk(KERN_ERR "%s: User [%d] does not have a daemon " | 491 | printk(KERN_ERR "%s: User [%d] does not have a daemon " |