From 0fd4fe9262c4757169570551f9633a56fd71a91c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 11 Jul 2012 08:41:49 -0700 Subject: [PATCH] 3.4-stable patches added patches: ecryptfs-fix-lockdep-warning-in-miscdev-operations.patch ecryptfs-gracefully-refuse-miscdev-file-ops-on-inherited-passed-files.patch ecryptfs-properly-check-for-o_rdonly-flag-before-doing-privileged-open.patch --- ...ockdep-warning-in-miscdev-operations.patch | 103 ++++++++++++++++++ ...v-file-ops-on-inherited-passed-files.patch | 95 ++++++++++++++++ ...ly-flag-before-doing-privileged-open.patch | 42 +++++++ queue-3.4/series | 3 + 4 files changed, 243 insertions(+) create mode 100644 queue-3.4/ecryptfs-fix-lockdep-warning-in-miscdev-operations.patch create mode 100644 queue-3.4/ecryptfs-gracefully-refuse-miscdev-file-ops-on-inherited-passed-files.patch create mode 100644 queue-3.4/ecryptfs-properly-check-for-o_rdonly-flag-before-doing-privileged-open.patch diff --git a/queue-3.4/ecryptfs-fix-lockdep-warning-in-miscdev-operations.patch b/queue-3.4/ecryptfs-fix-lockdep-warning-in-miscdev-operations.patch new file mode 100644 index 00000000000..d557282e789 --- /dev/null +++ b/queue-3.4/ecryptfs-fix-lockdep-warning-in-miscdev-operations.patch @@ -0,0 +1,103 @@ +From 60d65f1f07a7d81d3eb3b91fc13fca80f2fdbb12 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Mon, 11 Jun 2012 10:21:34 -0700 +Subject: eCryptfs: Fix lockdep warning in miscdev operations + +From: Tyler Hicks + +commit 60d65f1f07a7d81d3eb3b91fc13fca80f2fdbb12 upstream. + +Don't grab the daemon mutex while holding the message context mutex. +Addresses this lockdep warning: + + ecryptfsd/2141 is trying to acquire lock: + (&ecryptfs_msg_ctx_arr[i].mux){+.+.+.}, at: [] ecryptfs_miscdev_read+0x143/0x470 [ecryptfs] + + but task is already holding lock: + (&(*daemon)->mux){+.+...}, at: [] ecryptfs_miscdev_read+0x21c/0x470 [ecryptfs] + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #1 (&(*daemon)->mux){+.+...}: + [] lock_acquire+0x9d/0x220 + [] __mutex_lock_common+0x5a/0x4b0 + [] mutex_lock_nested+0x44/0x50 + [] ecryptfs_send_miscdev+0x97/0x120 [ecryptfs] + [] ecryptfs_send_message+0x134/0x1e0 [ecryptfs] + [] ecryptfs_generate_key_packet_set+0x2fe/0xa80 [ecryptfs] + [] ecryptfs_write_metadata+0x108/0x250 [ecryptfs] + [] ecryptfs_create+0x130/0x250 [ecryptfs] + [] vfs_create+0xb4/0x120 + [] do_last+0x8c5/0xa10 + [] path_openat+0xd9/0x460 + [] do_filp_open+0x42/0xa0 + [] do_sys_open+0xf8/0x1d0 + [] sys_open+0x21/0x30 + [] system_call_fastpath+0x16/0x1b + + -> #0 (&ecryptfs_msg_ctx_arr[i].mux){+.+.+.}: + [] __lock_acquire+0x1bf8/0x1c50 + [] lock_acquire+0x9d/0x220 + [] __mutex_lock_common+0x5a/0x4b0 + [] mutex_lock_nested+0x44/0x50 + [] ecryptfs_miscdev_read+0x143/0x470 [ecryptfs] + [] vfs_read+0xb3/0x180 + [] sys_read+0x4d/0x90 + [] system_call_fastpath+0x16/0x1b + +Signed-off-by: Tyler Hicks +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/miscdev.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +--- a/fs/ecryptfs/miscdev.c ++++ b/fs/ecryptfs/miscdev.c +@@ -195,31 +195,32 @@ int ecryptfs_send_miscdev(char *data, si + struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, + u16 msg_flags, struct ecryptfs_daemon *daemon) + { +- int rc = 0; ++ struct ecryptfs_message *msg; + +- mutex_lock(&msg_ctx->mux); +- msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), +- GFP_KERNEL); +- if (!msg_ctx->msg) { +- rc = -ENOMEM; ++ msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL); ++ if (!msg) { + printk(KERN_ERR "%s: Out of memory whilst attempting " + "to kmalloc(%zd, GFP_KERNEL)\n", __func__, +- (sizeof(*msg_ctx->msg) + data_size)); +- goto out_unlock; ++ (sizeof(*msg) + data_size)); ++ return -ENOMEM; + } ++ ++ mutex_lock(&msg_ctx->mux); ++ msg_ctx->msg = msg; + msg_ctx->msg->index = msg_ctx->index; + msg_ctx->msg->data_len = data_size; + msg_ctx->type = msg_type; + memcpy(msg_ctx->msg->data, data, data_size); + msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); +- mutex_lock(&daemon->mux); + list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); ++ mutex_unlock(&msg_ctx->mux); ++ ++ mutex_lock(&daemon->mux); + daemon->num_queued_msg_ctx++; + wake_up_interruptible(&daemon->wait); + mutex_unlock(&daemon->mux); +-out_unlock: +- mutex_unlock(&msg_ctx->mux); +- return rc; ++ ++ return 0; + } + + /* diff --git a/queue-3.4/ecryptfs-gracefully-refuse-miscdev-file-ops-on-inherited-passed-files.patch b/queue-3.4/ecryptfs-gracefully-refuse-miscdev-file-ops-on-inherited-passed-files.patch new file mode 100644 index 00000000000..f60a64c09d9 --- /dev/null +++ b/queue-3.4/ecryptfs-gracefully-refuse-miscdev-file-ops-on-inherited-passed-files.patch @@ -0,0 +1,95 @@ +From 8dc6780587c99286c0d3de747a2946a76989414a Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Mon, 11 Jun 2012 09:24:11 -0700 +Subject: eCryptfs: Gracefully refuse miscdev file ops on inherited/passed files + +From: Tyler Hicks + +commit 8dc6780587c99286c0d3de747a2946a76989414a upstream. + +File operations on /dev/ecryptfs would BUG() when the operations were +performed by processes other than the process that originally opened the +file. This could happen with open files inherited after fork() or file +descriptors passed through IPC mechanisms. Rather than calling BUG(), an +error code can be safely returned in most situations. + +In ecryptfs_miscdev_release(), eCryptfs still needs to handle the +release even if the last file reference is being held by a process that +didn't originally open the file. ecryptfs_find_daemon_by_euid() will not +be successful, so a pointer to the daemon is stored in the file's +private_data. The private_data pointer is initialized when the miscdev +file is opened and only used when the file is released. + +https://launchpad.net/bugs/994247 + +Signed-off-by: Tyler Hicks +Reported-by: Sasha Levin +Tested-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/miscdev.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +--- a/fs/ecryptfs/miscdev.c ++++ b/fs/ecryptfs/miscdev.c +@@ -49,7 +49,10 @@ ecryptfs_miscdev_poll(struct file *file, + mutex_lock(&ecryptfs_daemon_hash_mux); + /* TODO: Just use file->private_data? */ + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); +- BUG_ON(rc || !daemon); ++ if (rc || !daemon) { ++ mutex_unlock(&ecryptfs_daemon_hash_mux); ++ return -EINVAL; ++ } + mutex_lock(&daemon->mux); + mutex_unlock(&ecryptfs_daemon_hash_mux); + if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { +@@ -122,6 +125,7 @@ ecryptfs_miscdev_open(struct inode *inod + goto out_unlock_daemon; + } + daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; ++ file->private_data = daemon; + atomic_inc(&ecryptfs_num_miscdev_opens); + out_unlock_daemon: + mutex_unlock(&daemon->mux); +@@ -152,9 +156,9 @@ ecryptfs_miscdev_release(struct inode *i + + mutex_lock(&ecryptfs_daemon_hash_mux); + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); +- BUG_ON(rc || !daemon); ++ if (rc || !daemon) ++ daemon = file->private_data; + mutex_lock(&daemon->mux); +- BUG_ON(daemon->pid != task_pid(current)); + BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); + daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; + atomic_dec(&ecryptfs_num_miscdev_opens); +@@ -269,8 +273,16 @@ ecryptfs_miscdev_read(struct file *file, + mutex_lock(&ecryptfs_daemon_hash_mux); + /* TODO: Just use file->private_data? */ + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); +- BUG_ON(rc || !daemon); ++ if (rc || !daemon) { ++ mutex_unlock(&ecryptfs_daemon_hash_mux); ++ return -EINVAL; ++ } + mutex_lock(&daemon->mux); ++ if (task_pid(current) != daemon->pid) { ++ mutex_unlock(&daemon->mux); ++ mutex_unlock(&ecryptfs_daemon_hash_mux); ++ return -EPERM; ++ } + if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { + rc = 0; + mutex_unlock(&ecryptfs_daemon_hash_mux); +@@ -307,9 +319,6 @@ check_list: + * message from the queue; try again */ + goto check_list; + } +- BUG_ON(euid != daemon->euid); +- BUG_ON(current_user_ns() != daemon->user_ns); +- BUG_ON(task_pid(current) != daemon->pid); + msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, + struct ecryptfs_msg_ctx, daemon_out_list); + BUG_ON(!msg_ctx); diff --git a/queue-3.4/ecryptfs-properly-check-for-o_rdonly-flag-before-doing-privileged-open.patch b/queue-3.4/ecryptfs-properly-check-for-o_rdonly-flag-before-doing-privileged-open.patch new file mode 100644 index 00000000000..c2a913b4d4c --- /dev/null +++ b/queue-3.4/ecryptfs-properly-check-for-o_rdonly-flag-before-doing-privileged-open.patch @@ -0,0 +1,42 @@ +From 9fe79d7600497ed8a95c3981cbe5b73ab98222f0 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Tue, 12 Jun 2012 11:17:01 -0700 +Subject: eCryptfs: Properly check for O_RDONLY flag before doing privileged open + +From: Tyler Hicks + +commit 9fe79d7600497ed8a95c3981cbe5b73ab98222f0 upstream. + +If the first attempt at opening the lower file read/write fails, +eCryptfs will retry using a privileged kthread. However, the privileged +retry should not happen if the lower file's inode is read-only because a +read/write open will still be unsuccessful. + +The check for determining if the open should be retried was intended to +be based on the access mode of the lower file's open flags being +O_RDONLY, but the check was incorrectly performed. This would cause the +open to be retried by the privileged kthread, resulting in a second +failed open of the lower file. This patch corrects the check to +determine if the open request should be handled by the privileged +kthread. + +Signed-off-by: Tyler Hicks +Reported-by: Dan Carpenter +Acked-by: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/kthread.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ecryptfs/kthread.c ++++ b/fs/ecryptfs/kthread.c +@@ -149,7 +149,7 @@ int ecryptfs_privileged_open(struct file + (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred); + if (!IS_ERR(*lower_file)) + goto out; +- if (flags & O_RDONLY) { ++ if ((flags & O_ACCMODE) == O_RDONLY) { + rc = PTR_ERR((*lower_file)); + goto out; + } diff --git a/queue-3.4/series b/queue-3.4/series index f63a51509ed..3d012c190cb 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -131,3 +131,6 @@ dm-verity-fix-documentation.patch dm-persistent-data-fix-shadow_info_leak-on-dm_tm_destroy.patch dm-persistent-data-handle-space-map-checker-creation-failure.patch dm-persistent-data-fix-allocation-failure-in-space-map-checker-init.patch +ecryptfs-gracefully-refuse-miscdev-file-ops-on-inherited-passed-files.patch +ecryptfs-fix-lockdep-warning-in-miscdev-operations.patch +ecryptfs-properly-check-for-o_rdonly-flag-before-doing-privileged-open.patch -- 2.47.3