Skip to content

Commit 26c439d

Browse files
committed
Merge tag 'ecryptfs-3.5-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs
Pull eCryptfs fixes from Tyler Hicks: "Fixes an incorrect access mode check when preparing to open a file in the lower filesystem. This isn't an urgent fix, but it is simple and the check was obviously incorrect. Also fixes a couple important bugs in the eCryptfs miscdev interface. These changes are low risk due to the small number of users that use the miscdev interface. I was able to keep the changes minimal and I have some cleaner, more complete changes queued up for the next merge window that will build on these patches." * tag 'ecryptfs-3.5-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs: eCryptfs: Gracefully refuse miscdev file ops on inherited/passed files eCryptfs: Fix lockdep warning in miscdev operations eCryptfs: Properly check for O_RDONLY flag before doing privileged open
2 parents c8912f2 + 8dc6780 commit 26c439d

File tree

2 files changed

+30
-20
lines changed

2 files changed

+30
-20
lines changed

fs/ecryptfs/kthread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
149149
(*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred);
150150
if (!IS_ERR(*lower_file))
151151
goto out;
152-
if (flags & O_RDONLY) {
152+
if ((flags & O_ACCMODE) == O_RDONLY) {
153153
rc = PTR_ERR((*lower_file));
154154
goto out;
155155
}

fs/ecryptfs/miscdev.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt)
4949
mutex_lock(&ecryptfs_daemon_hash_mux);
5050
/* TODO: Just use file->private_data? */
5151
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
52-
BUG_ON(rc || !daemon);
52+
if (rc || !daemon) {
53+
mutex_unlock(&ecryptfs_daemon_hash_mux);
54+
return -EINVAL;
55+
}
5356
mutex_lock(&daemon->mux);
5457
mutex_unlock(&ecryptfs_daemon_hash_mux);
5558
if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
@@ -122,6 +125,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
122125
goto out_unlock_daemon;
123126
}
124127
daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN;
128+
file->private_data = daemon;
125129
atomic_inc(&ecryptfs_num_miscdev_opens);
126130
out_unlock_daemon:
127131
mutex_unlock(&daemon->mux);
@@ -152,9 +156,9 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file)
152156

153157
mutex_lock(&ecryptfs_daemon_hash_mux);
154158
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
155-
BUG_ON(rc || !daemon);
159+
if (rc || !daemon)
160+
daemon = file->private_data;
156161
mutex_lock(&daemon->mux);
157-
BUG_ON(daemon->pid != task_pid(current));
158162
BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN));
159163
daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN;
160164
atomic_dec(&ecryptfs_num_miscdev_opens);
@@ -191,31 +195,32 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
191195
struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
192196
u16 msg_flags, struct ecryptfs_daemon *daemon)
193197
{
194-
int rc = 0;
198+
struct ecryptfs_message *msg;
195199

196-
mutex_lock(&msg_ctx->mux);
197-
msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size),
198-
GFP_KERNEL);
199-
if (!msg_ctx->msg) {
200-
rc = -ENOMEM;
200+
msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL);
201+
if (!msg) {
201202
printk(KERN_ERR "%s: Out of memory whilst attempting "
202203
"to kmalloc(%zd, GFP_KERNEL)\n", __func__,
203-
(sizeof(*msg_ctx->msg) + data_size));
204-
goto out_unlock;
204+
(sizeof(*msg) + data_size));
205+
return -ENOMEM;
205206
}
207+
208+
mutex_lock(&msg_ctx->mux);
209+
msg_ctx->msg = msg;
206210
msg_ctx->msg->index = msg_ctx->index;
207211
msg_ctx->msg->data_len = data_size;
208212
msg_ctx->type = msg_type;
209213
memcpy(msg_ctx->msg->data, data, data_size);
210214
msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size);
211-
mutex_lock(&daemon->mux);
212215
list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue);
216+
mutex_unlock(&msg_ctx->mux);
217+
218+
mutex_lock(&daemon->mux);
213219
daemon->num_queued_msg_ctx++;
214220
wake_up_interruptible(&daemon->wait);
215221
mutex_unlock(&daemon->mux);
216-
out_unlock:
217-
mutex_unlock(&msg_ctx->mux);
218-
return rc;
222+
223+
return 0;
219224
}
220225

221226
/*
@@ -269,8 +274,16 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
269274
mutex_lock(&ecryptfs_daemon_hash_mux);
270275
/* TODO: Just use file->private_data? */
271276
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
272-
BUG_ON(rc || !daemon);
277+
if (rc || !daemon) {
278+
mutex_unlock(&ecryptfs_daemon_hash_mux);
279+
return -EINVAL;
280+
}
273281
mutex_lock(&daemon->mux);
282+
if (task_pid(current) != daemon->pid) {
283+
mutex_unlock(&daemon->mux);
284+
mutex_unlock(&ecryptfs_daemon_hash_mux);
285+
return -EPERM;
286+
}
274287
if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
275288
rc = 0;
276289
mutex_unlock(&ecryptfs_daemon_hash_mux);
@@ -307,9 +320,6 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
307320
* message from the queue; try again */
308321
goto check_list;
309322
}
310-
BUG_ON(euid != daemon->euid);
311-
BUG_ON(current_user_ns() != daemon->user_ns);
312-
BUG_ON(task_pid(current) != daemon->pid);
313323
msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue,
314324
struct ecryptfs_msg_ctx, daemon_out_list);
315325
BUG_ON(!msg_ctx);

0 commit comments

Comments
 (0)