diff options
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 25 | ||||
-rw-r--r-- | fs/ecryptfs/messaging.c | 81 | ||||
-rw-r--r-- | fs/ecryptfs/miscdev.c | 68 | ||||
-rw-r--r-- | fs/ecryptfs/netlink.c | 25 | ||||
-rw-r--r-- | kernel/user_namespace.c | 1 |
5 files changed, 136 insertions, 64 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 72e117706a68..951ee33a022d 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
35 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <linux/hash.h> | 36 | #include <linux/hash.h> |
37 | #include <linux/nsproxy.h> | ||
37 | 38 | ||
38 | /* Version verification for shared data structures w/ userspace */ | 39 | /* Version verification for shared data structures w/ userspace */ |
39 | #define ECRYPTFS_VERSION_MAJOR 0x00 | 40 | #define ECRYPTFS_VERSION_MAJOR 0x00 |
@@ -410,8 +411,9 @@ struct ecryptfs_daemon { | |||
410 | #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 | 411 | #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 |
411 | u32 flags; | 412 | u32 flags; |
412 | u32 num_queued_msg_ctx; | 413 | u32 num_queued_msg_ctx; |
413 | pid_t pid; | 414 | struct pid *pid; |
414 | uid_t euid; | 415 | uid_t euid; |
416 | struct user_namespace *user_ns; | ||
415 | struct task_struct *task; | 417 | struct task_struct *task; |
416 | struct mutex mux; | 418 | struct mutex mux; |
417 | struct list_head msg_ctx_out_queue; | 419 | struct list_head msg_ctx_out_queue; |
@@ -610,10 +612,13 @@ int | |||
610 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 612 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
611 | size_t size, int flags); | 613 | size_t size, int flags); |
612 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); | 614 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); |
613 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); | 615 | int ecryptfs_process_helo(unsigned int transport, uid_t euid, |
614 | int ecryptfs_process_quit(uid_t uid, pid_t pid); | 616 | struct user_namespace *user_ns, struct pid *pid); |
615 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | 617 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, |
616 | pid_t pid, u32 seq); | 618 | struct pid *pid); |
619 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | ||
620 | struct user_namespace *user_ns, struct pid *pid, | ||
621 | u32 seq); | ||
617 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | 622 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, |
618 | struct ecryptfs_msg_ctx **msg_ctx); | 623 | struct ecryptfs_msg_ctx **msg_ctx); |
619 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | 624 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, |
@@ -623,13 +628,13 @@ void ecryptfs_release_messaging(unsigned int transport); | |||
623 | 628 | ||
624 | int ecryptfs_send_netlink(char *data, int data_len, | 629 | int ecryptfs_send_netlink(char *data, int data_len, |
625 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, | 630 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
626 | u16 msg_flags, pid_t daemon_pid); | 631 | u16 msg_flags, struct pid *daemon_pid); |
627 | int ecryptfs_init_netlink(void); | 632 | int ecryptfs_init_netlink(void); |
628 | void ecryptfs_release_netlink(void); | 633 | void ecryptfs_release_netlink(void); |
629 | 634 | ||
630 | int ecryptfs_send_connector(char *data, int data_len, | 635 | int ecryptfs_send_connector(char *data, int data_len, |
631 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, | 636 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
632 | u16 msg_flags, pid_t daemon_pid); | 637 | u16 msg_flags, struct pid *daemon_pid); |
633 | int ecryptfs_init_connector(void); | 638 | int ecryptfs_init_connector(void); |
634 | void ecryptfs_release_connector(void); | 639 | void ecryptfs_release_connector(void); |
635 | void | 640 | void |
@@ -672,7 +677,8 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
672 | struct inode *ecryptfs_inode); | 677 | struct inode *ecryptfs_inode); |
673 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); | 678 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); |
674 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); | 679 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); |
675 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid); | 680 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, |
681 | struct user_namespace *user_ns); | ||
676 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, | 682 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, |
677 | size_t *length_size); | 683 | size_t *length_size); |
678 | int ecryptfs_write_packet_length(char *dest, size_t size, | 684 | int ecryptfs_write_packet_length(char *dest, size_t size, |
@@ -684,6 +690,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
684 | u16 msg_flags, struct ecryptfs_daemon *daemon); | 690 | u16 msg_flags, struct ecryptfs_daemon *daemon); |
685 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); | 691 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); |
686 | int | 692 | int |
687 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, pid_t pid); | 693 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, |
694 | struct user_namespace *user_ns, struct pid *pid); | ||
688 | 695 | ||
689 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 696 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
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 " |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 0c559731ae34..788995efd1d3 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -46,7 +46,8 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt) | |||
46 | 46 | ||
47 | mutex_lock(&ecryptfs_daemon_hash_mux); | 47 | mutex_lock(&ecryptfs_daemon_hash_mux); |
48 | /* TODO: Just use file->private_data? */ | 48 | /* TODO: Just use file->private_data? */ |
49 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid); | 49 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, |
50 | current->nsproxy->user_ns); | ||
50 | BUG_ON(rc || !daemon); | 51 | BUG_ON(rc || !daemon); |
51 | mutex_lock(&daemon->mux); | 52 | mutex_lock(&daemon->mux); |
52 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 53 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
@@ -92,10 +93,12 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
92 | "count; rc = [%d]\n", __func__, rc); | 93 | "count; rc = [%d]\n", __func__, rc); |
93 | goto out_unlock_daemon_list; | 94 | goto out_unlock_daemon_list; |
94 | } | 95 | } |
95 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid); | 96 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, |
97 | current->nsproxy->user_ns); | ||
96 | if (rc || !daemon) { | 98 | if (rc || !daemon) { |
97 | rc = ecryptfs_spawn_daemon(&daemon, current->euid, | 99 | rc = ecryptfs_spawn_daemon(&daemon, current->euid, |
98 | current->pid); | 100 | current->nsproxy->user_ns, |
101 | task_pid(current)); | ||
99 | if (rc) { | 102 | if (rc) { |
100 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " | 103 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " |
101 | "rc = [%d]\n", __func__, rc); | 104 | "rc = [%d]\n", __func__, rc); |
@@ -103,18 +106,18 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
103 | } | 106 | } |
104 | } | 107 | } |
105 | mutex_lock(&daemon->mux); | 108 | mutex_lock(&daemon->mux); |
106 | if (daemon->pid != current->pid) { | 109 | if (daemon->pid != task_pid(current)) { |
107 | rc = -EINVAL; | 110 | rc = -EINVAL; |
108 | printk(KERN_ERR "%s: pid [%d] has registered with euid [%d], " | 111 | printk(KERN_ERR "%s: pid [0x%p] has registered with euid [%d], " |
109 | "but pid [%d] has attempted to open the handle " | 112 | "but pid [0x%p] has attempted to open the handle " |
110 | "instead\n", __func__, daemon->pid, daemon->euid, | 113 | "instead\n", __func__, daemon->pid, daemon->euid, |
111 | current->pid); | 114 | task_pid(current)); |
112 | goto out_unlock_daemon; | 115 | goto out_unlock_daemon; |
113 | } | 116 | } |
114 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { | 117 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { |
115 | rc = -EBUSY; | 118 | rc = -EBUSY; |
116 | printk(KERN_ERR "%s: Miscellaneous device handle may only be " | 119 | printk(KERN_ERR "%s: Miscellaneous device handle may only be " |
117 | "opened once per daemon; pid [%d] already has this " | 120 | "opened once per daemon; pid [0x%p] already has this " |
118 | "handle open\n", __func__, daemon->pid); | 121 | "handle open\n", __func__, daemon->pid); |
119 | goto out_unlock_daemon; | 122 | goto out_unlock_daemon; |
120 | } | 123 | } |
@@ -147,10 +150,11 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) | |||
147 | int rc; | 150 | int rc; |
148 | 151 | ||
149 | mutex_lock(&ecryptfs_daemon_hash_mux); | 152 | mutex_lock(&ecryptfs_daemon_hash_mux); |
150 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid); | 153 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, |
154 | current->nsproxy->user_ns); | ||
151 | BUG_ON(rc || !daemon); | 155 | BUG_ON(rc || !daemon); |
152 | mutex_lock(&daemon->mux); | 156 | mutex_lock(&daemon->mux); |
153 | BUG_ON(daemon->pid != current->pid); | 157 | BUG_ON(daemon->pid != task_pid(current)); |
154 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); | 158 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); |
155 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; | 159 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; |
156 | atomic_dec(&ecryptfs_num_miscdev_opens); | 160 | atomic_dec(&ecryptfs_num_miscdev_opens); |
@@ -247,7 +251,8 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | |||
247 | 251 | ||
248 | mutex_lock(&ecryptfs_daemon_hash_mux); | 252 | mutex_lock(&ecryptfs_daemon_hash_mux); |
249 | /* TODO: Just use file->private_data? */ | 253 | /* TODO: Just use file->private_data? */ |
250 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid); | 254 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, |
255 | current->nsproxy->user_ns); | ||
251 | BUG_ON(rc || !daemon); | 256 | BUG_ON(rc || !daemon); |
252 | mutex_lock(&daemon->mux); | 257 | mutex_lock(&daemon->mux); |
253 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 258 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
@@ -285,7 +290,8 @@ check_list: | |||
285 | goto check_list; | 290 | goto check_list; |
286 | } | 291 | } |
287 | BUG_ON(current->euid != daemon->euid); | 292 | BUG_ON(current->euid != daemon->euid); |
288 | BUG_ON(current->pid != daemon->pid); | 293 | BUG_ON(current->nsproxy->user_ns != daemon->user_ns); |
294 | BUG_ON(task_pid(current) != daemon->pid); | ||
289 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, | 295 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, |
290 | struct ecryptfs_msg_ctx, daemon_out_list); | 296 | struct ecryptfs_msg_ctx, daemon_out_list); |
291 | BUG_ON(!msg_ctx); | 297 | BUG_ON(!msg_ctx); |
@@ -355,15 +361,18 @@ out_unlock_daemon: | |||
355 | /** | 361 | /** |
356 | * ecryptfs_miscdev_helo | 362 | * ecryptfs_miscdev_helo |
357 | * @euid: effective user id of miscdevess sending helo packet | 363 | * @euid: effective user id of miscdevess sending helo packet |
364 | * @user_ns: The namespace in which @euid applies | ||
358 | * @pid: miscdevess id of miscdevess sending helo packet | 365 | * @pid: miscdevess id of miscdevess sending helo packet |
359 | * | 366 | * |
360 | * Returns zero on success; non-zero otherwise | 367 | * Returns zero on success; non-zero otherwise |
361 | */ | 368 | */ |
362 | static int ecryptfs_miscdev_helo(uid_t uid, pid_t pid) | 369 | static int ecryptfs_miscdev_helo(uid_t euid, struct user_namespace *user_ns, |
370 | struct pid *pid) | ||
363 | { | 371 | { |
364 | int rc; | 372 | int rc; |
365 | 373 | ||
366 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_MISCDEV, uid, pid); | 374 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_MISCDEV, euid, user_ns, |
375 | pid); | ||
367 | if (rc) | 376 | if (rc) |
368 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); | 377 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); |
369 | return rc; | 378 | return rc; |
@@ -372,15 +381,17 @@ static int ecryptfs_miscdev_helo(uid_t uid, pid_t pid) | |||
372 | /** | 381 | /** |
373 | * ecryptfs_miscdev_quit | 382 | * ecryptfs_miscdev_quit |
374 | * @euid: effective user id of miscdevess sending quit packet | 383 | * @euid: effective user id of miscdevess sending quit packet |
384 | * @user_ns: The namespace in which @euid applies | ||
375 | * @pid: miscdevess id of miscdevess sending quit packet | 385 | * @pid: miscdevess id of miscdevess sending quit packet |
376 | * | 386 | * |
377 | * Returns zero on success; non-zero otherwise | 387 | * Returns zero on success; non-zero otherwise |
378 | */ | 388 | */ |
379 | static int ecryptfs_miscdev_quit(uid_t euid, pid_t pid) | 389 | static int ecryptfs_miscdev_quit(uid_t euid, struct user_namespace *user_ns, |
390 | struct pid *pid) | ||
380 | { | 391 | { |
381 | int rc; | 392 | int rc; |
382 | 393 | ||
383 | rc = ecryptfs_process_quit(euid, pid); | 394 | rc = ecryptfs_process_quit(euid, user_ns, pid); |
384 | if (rc) | 395 | if (rc) |
385 | printk(KERN_WARNING | 396 | printk(KERN_WARNING |
386 | "Error processing QUIT message; rc = [%d]\n", rc); | 397 | "Error processing QUIT message; rc = [%d]\n", rc); |
@@ -392,13 +403,15 @@ static int ecryptfs_miscdev_quit(uid_t euid, pid_t pid) | |||
392 | * @data: Bytes comprising struct ecryptfs_message | 403 | * @data: Bytes comprising struct ecryptfs_message |
393 | * @data_size: sizeof(struct ecryptfs_message) + data len | 404 | * @data_size: sizeof(struct ecryptfs_message) + data len |
394 | * @euid: Effective user id of miscdevess sending the miscdev response | 405 | * @euid: Effective user id of miscdevess sending the miscdev response |
406 | * @user_ns: The namespace in which @euid applies | ||
395 | * @pid: Miscdevess id of miscdevess sending the miscdev response | 407 | * @pid: Miscdevess id of miscdevess sending the miscdev response |
396 | * @seq: Sequence number for miscdev response packet | 408 | * @seq: Sequence number for miscdev response packet |
397 | * | 409 | * |
398 | * Returns zero on success; non-zero otherwise | 410 | * Returns zero on success; non-zero otherwise |
399 | */ | 411 | */ |
400 | static int ecryptfs_miscdev_response(char *data, size_t data_size, | 412 | static int ecryptfs_miscdev_response(char *data, size_t data_size, |
401 | uid_t euid, pid_t pid, u32 seq) | 413 | uid_t euid, struct user_namespace *user_ns, |
414 | struct pid *pid, u32 seq) | ||
402 | { | 415 | { |
403 | struct ecryptfs_message *msg = (struct ecryptfs_message *)data; | 416 | struct ecryptfs_message *msg = (struct ecryptfs_message *)data; |
404 | int rc; | 417 | int rc; |
@@ -410,7 +423,7 @@ static int ecryptfs_miscdev_response(char *data, size_t data_size, | |||
410 | rc = -EINVAL; | 423 | rc = -EINVAL; |
411 | goto out; | 424 | goto out; |
412 | } | 425 | } |
413 | rc = ecryptfs_process_response(msg, euid, pid, seq); | 426 | rc = ecryptfs_process_response(msg, euid, user_ns, pid, seq); |
414 | if (rc) | 427 | if (rc) |
415 | printk(KERN_ERR | 428 | printk(KERN_ERR |
416 | "Error processing response message; rc = [%d]\n", rc); | 429 | "Error processing response message; rc = [%d]\n", rc); |
@@ -491,27 +504,32 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
491 | } | 504 | } |
492 | rc = ecryptfs_miscdev_response(&data[i], packet_size, | 505 | rc = ecryptfs_miscdev_response(&data[i], packet_size, |
493 | current->euid, | 506 | current->euid, |
494 | current->pid, seq); | 507 | current->nsproxy->user_ns, |
508 | task_pid(current), seq); | ||
495 | if (rc) | 509 | if (rc) |
496 | printk(KERN_WARNING "%s: Failed to deliver miscdev " | 510 | printk(KERN_WARNING "%s: Failed to deliver miscdev " |
497 | "response to requesting operation; rc = [%d]\n", | 511 | "response to requesting operation; rc = [%d]\n", |
498 | __func__, rc); | 512 | __func__, rc); |
499 | break; | 513 | break; |
500 | case ECRYPTFS_MSG_HELO: | 514 | case ECRYPTFS_MSG_HELO: |
501 | rc = ecryptfs_miscdev_helo(current->euid, current->pid); | 515 | rc = ecryptfs_miscdev_helo(current->euid, |
516 | current->nsproxy->user_ns, | ||
517 | task_pid(current)); | ||
502 | if (rc) { | 518 | if (rc) { |
503 | printk(KERN_ERR "%s: Error attempting to process " | 519 | printk(KERN_ERR "%s: Error attempting to process " |
504 | "helo from pid [%d]; rc = [%d]\n", __func__, | 520 | "helo from pid [0x%p]; rc = [%d]\n", __func__, |
505 | current->pid, rc); | 521 | task_pid(current), rc); |
506 | goto out_free; | 522 | goto out_free; |
507 | } | 523 | } |
508 | break; | 524 | break; |
509 | case ECRYPTFS_MSG_QUIT: | 525 | case ECRYPTFS_MSG_QUIT: |
510 | rc = ecryptfs_miscdev_quit(current->euid, current->pid); | 526 | rc = ecryptfs_miscdev_quit(current->euid, |
527 | current->nsproxy->user_ns, | ||
528 | task_pid(current)); | ||
511 | if (rc) { | 529 | if (rc) { |
512 | printk(KERN_ERR "%s: Error attempting to process " | 530 | printk(KERN_ERR "%s: Error attempting to process " |
513 | "quit from pid [%d]; rc = [%d]\n", __func__, | 531 | "quit from pid [0x%p]; rc = [%d]\n", __func__, |
514 | current->pid, rc); | 532 | task_pid(current), rc); |
515 | goto out_free; | 533 | goto out_free; |
516 | } | 534 | } |
517 | break; | 535 | break; |
diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c index eb70f69d705d..e0abad62b395 100644 --- a/fs/ecryptfs/netlink.c +++ b/fs/ecryptfs/netlink.c | |||
@@ -45,7 +45,7 @@ static struct sock *ecryptfs_nl_sock; | |||
45 | */ | 45 | */ |
46 | int ecryptfs_send_netlink(char *data, int data_len, | 46 | int ecryptfs_send_netlink(char *data, int data_len, |
47 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, | 47 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
48 | u16 msg_flags, pid_t daemon_pid) | 48 | u16 msg_flags, struct pid *daemon_pid) |
49 | { | 49 | { |
50 | struct sk_buff *skb; | 50 | struct sk_buff *skb; |
51 | struct nlmsghdr *nlh; | 51 | struct nlmsghdr *nlh; |
@@ -60,7 +60,7 @@ int ecryptfs_send_netlink(char *data, int data_len, | |||
60 | ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n"); | 60 | ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n"); |
61 | goto out; | 61 | goto out; |
62 | } | 62 | } |
63 | nlh = NLMSG_PUT(skb, daemon_pid, msg_ctx ? msg_ctx->counter : 0, | 63 | nlh = NLMSG_PUT(skb, pid_nr(daemon_pid), msg_ctx ? msg_ctx->counter : 0, |
64 | msg_type, payload_len); | 64 | msg_type, payload_len); |
65 | nlh->nlmsg_flags = msg_flags; | 65 | nlh->nlmsg_flags = msg_flags; |
66 | if (msg_ctx && payload_len) { | 66 | if (msg_ctx && payload_len) { |
@@ -69,7 +69,7 @@ int ecryptfs_send_netlink(char *data, int data_len, | |||
69 | msg->data_len = data_len; | 69 | msg->data_len = data_len; |
70 | memcpy(msg->data, data, data_len); | 70 | memcpy(msg->data, data, data_len); |
71 | } | 71 | } |
72 | rc = netlink_unicast(ecryptfs_nl_sock, skb, daemon_pid, 0); | 72 | rc = netlink_unicast(ecryptfs_nl_sock, skb, pid_nr(daemon_pid), 0); |
73 | if (rc < 0) { | 73 | if (rc < 0) { |
74 | ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink " | 74 | ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink " |
75 | "message; rc = [%d]\n", rc); | 75 | "message; rc = [%d]\n", rc); |
@@ -99,6 +99,7 @@ static int ecryptfs_process_nl_response(struct sk_buff *skb) | |||
99 | { | 99 | { |
100 | struct nlmsghdr *nlh = nlmsg_hdr(skb); | 100 | struct nlmsghdr *nlh = nlmsg_hdr(skb); |
101 | struct ecryptfs_message *msg = NLMSG_DATA(nlh); | 101 | struct ecryptfs_message *msg = NLMSG_DATA(nlh); |
102 | struct pid *pid; | ||
102 | int rc; | 103 | int rc; |
103 | 104 | ||
104 | if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) { | 105 | if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) { |
@@ -107,8 +108,10 @@ static int ecryptfs_process_nl_response(struct sk_buff *skb) | |||
107 | "incorrectly specified data length\n"); | 108 | "incorrectly specified data length\n"); |
108 | goto out; | 109 | goto out; |
109 | } | 110 | } |
110 | rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, | 111 | pid = find_get_pid(NETLINK_CREDS(skb)->pid); |
111 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq); | 112 | rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, NULL, |
113 | pid, nlh->nlmsg_seq); | ||
114 | put_pid(pid); | ||
112 | if (rc) | 115 | if (rc) |
113 | printk(KERN_ERR | 116 | printk(KERN_ERR |
114 | "Error processing response message; rc = [%d]\n", rc); | 117 | "Error processing response message; rc = [%d]\n", rc); |
@@ -126,11 +129,13 @@ out: | |||
126 | */ | 129 | */ |
127 | static int ecryptfs_process_nl_helo(struct sk_buff *skb) | 130 | static int ecryptfs_process_nl_helo(struct sk_buff *skb) |
128 | { | 131 | { |
132 | struct pid *pid; | ||
129 | int rc; | 133 | int rc; |
130 | 134 | ||
135 | pid = find_get_pid(NETLINK_CREDS(skb)->pid); | ||
131 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK, | 136 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK, |
132 | NETLINK_CREDS(skb)->uid, | 137 | NETLINK_CREDS(skb)->uid, NULL, pid); |
133 | NETLINK_CREDS(skb)->pid); | 138 | put_pid(pid); |
134 | if (rc) | 139 | if (rc) |
135 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); | 140 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); |
136 | return rc; | 141 | return rc; |
@@ -147,10 +152,12 @@ static int ecryptfs_process_nl_helo(struct sk_buff *skb) | |||
147 | */ | 152 | */ |
148 | static int ecryptfs_process_nl_quit(struct sk_buff *skb) | 153 | static int ecryptfs_process_nl_quit(struct sk_buff *skb) |
149 | { | 154 | { |
155 | struct pid *pid; | ||
150 | int rc; | 156 | int rc; |
151 | 157 | ||
152 | rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid, | 158 | pid = find_get_pid(NETLINK_CREDS(skb)->pid); |
153 | NETLINK_CREDS(skb)->pid); | 159 | rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid, NULL, pid); |
160 | put_pid(pid); | ||
154 | if (rc) | 161 | if (rc) |
155 | printk(KERN_WARNING | 162 | printk(KERN_WARNING |
156 | "Error processing QUIT message; rc = [%d]\n", rc); | 163 | "Error processing QUIT message; rc = [%d]\n", rc); |
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 2731ba80e30b..a9ab0596de44 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c | |||
@@ -74,3 +74,4 @@ void free_user_ns(struct kref *kref) | |||
74 | release_uids(ns); | 74 | release_uids(ns); |
75 | kfree(ns); | 75 | kfree(ns); |
76 | } | 76 | } |
77 | EXPORT_SYMBOL(free_user_ns); | ||