aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/kthread.c
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@linux.vnet.ibm.com>2009-08-12 02:06:54 -0400
committerTyler Hicks <tyhicks@linux.vnet.ibm.com>2009-09-23 10:10:32 -0400
commitac22ba23b659e34a5961aec8c945608e471b0d5b (patch)
tree6629c15380fe2db238fa078e912f4cf393708161 /fs/ecryptfs/kthread.c
parentb0105eaefa7cce8f4a941d0fc6354b250d30e745 (diff)
eCryptfs: Check for O_RDONLY lower inodes when opening lower files
If the lower inode is read-only, don't attempt to open the lower file read/write and don't hand off the open request to the privileged eCryptfs kthread for opening it read/write. Instead, only try an unprivileged, read-only open of the file and give up if that fails. This patch fixes an oops when eCryptfs is mounted on top of a read-only mount. Acked-by: Serge Hallyn <serue@us.ibm.com> Cc: Eric Sandeen <esandeen@redhat.com> Cc: Dave Kleikamp <shaggy@linux.vnet.ibm.com> Cc: ecryptfs-devel@lists.launchpad.net Cc: stable <stable@kernel.org> Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ecryptfs/kthread.c')
-rw-r--r--fs/ecryptfs/kthread.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index c6d7a4d748a0..e14cf7e588db 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -136,6 +136,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
136 const struct cred *cred) 136 const struct cred *cred)
137{ 137{
138 struct ecryptfs_open_req *req; 138 struct ecryptfs_open_req *req;
139 int flags = O_LARGEFILE;
139 int rc = 0; 140 int rc = 0;
140 141
141 /* Corresponding dput() and mntput() are done when the 142 /* Corresponding dput() and mntput() are done when the
@@ -143,10 +144,14 @@ int ecryptfs_privileged_open(struct file **lower_file,
143 * destroyed. */ 144 * destroyed. */
144 dget(lower_dentry); 145 dget(lower_dentry);
145 mntget(lower_mnt); 146 mntget(lower_mnt);
146 (*lower_file) = dentry_open(lower_dentry, lower_mnt, 147 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
147 (O_RDWR | O_LARGEFILE), cred); 148 (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred);
148 if (!IS_ERR(*lower_file)) 149 if (!IS_ERR(*lower_file))
149 goto out; 150 goto out;
151 if (flags & O_RDONLY) {
152 rc = PTR_ERR((*lower_file));
153 goto out;
154 }
150 req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL); 155 req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
151 if (!req) { 156 if (!req) {
152 rc = -ENOMEM; 157 rc = -ENOMEM;
@@ -180,21 +185,8 @@ int ecryptfs_privileged_open(struct file **lower_file,
180 __func__); 185 __func__);
181 goto out_unlock; 186 goto out_unlock;
182 } 187 }
183 if (IS_ERR(*req->lower_file)) { 188 if (IS_ERR(*req->lower_file))
184 rc = PTR_ERR(*req->lower_file); 189 rc = PTR_ERR(*req->lower_file);
185 dget(lower_dentry);
186 mntget(lower_mnt);
187 (*lower_file) = dentry_open(lower_dentry, lower_mnt,
188 (O_RDONLY | O_LARGEFILE), cred);
189 if (IS_ERR(*lower_file)) {
190 rc = PTR_ERR(*req->lower_file);
191 (*lower_file) = NULL;
192 printk(KERN_WARNING "%s: Error attempting privileged "
193 "open of lower file with either RW or RO "
194 "perms; rc = [%d]. Giving up.\n",
195 __func__, rc);
196 }
197 }
198out_unlock: 190out_unlock:
199 mutex_unlock(&req->mux); 191 mutex_unlock(&req->mux);
200out_free: 192out_free: