diff options
Diffstat (limited to 'fs/ecryptfs/miscdev.c')
| -rw-r--r-- | fs/ecryptfs/miscdev.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 3a06f4043df4..c0038f6566d4 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
| @@ -49,7 +49,10 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt) | |||
| 49 | mutex_lock(&ecryptfs_daemon_hash_mux); | 49 | mutex_lock(&ecryptfs_daemon_hash_mux); |
| 50 | /* TODO: Just use file->private_data? */ | 50 | /* TODO: Just use file->private_data? */ |
| 51 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 51 | 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 | } | ||
| 53 | mutex_lock(&daemon->mux); | 56 | mutex_lock(&daemon->mux); |
| 54 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 57 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
| 55 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 58 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
| @@ -122,6 +125,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
| 122 | goto out_unlock_daemon; | 125 | goto out_unlock_daemon; |
| 123 | } | 126 | } |
| 124 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; | 127 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; |
| 128 | file->private_data = daemon; | ||
| 125 | atomic_inc(&ecryptfs_num_miscdev_opens); | 129 | atomic_inc(&ecryptfs_num_miscdev_opens); |
| 126 | out_unlock_daemon: | 130 | out_unlock_daemon: |
| 127 | mutex_unlock(&daemon->mux); | 131 | mutex_unlock(&daemon->mux); |
| @@ -152,9 +156,9 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) | |||
| 152 | 156 | ||
| 153 | mutex_lock(&ecryptfs_daemon_hash_mux); | 157 | mutex_lock(&ecryptfs_daemon_hash_mux); |
| 154 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 158 | 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; | ||
| 156 | mutex_lock(&daemon->mux); | 161 | mutex_lock(&daemon->mux); |
| 157 | BUG_ON(daemon->pid != task_pid(current)); | ||
| 158 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); | 162 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); |
| 159 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; | 163 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; |
| 160 | atomic_dec(&ecryptfs_num_miscdev_opens); | 164 | atomic_dec(&ecryptfs_num_miscdev_opens); |
| @@ -191,31 +195,32 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
| 191 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, | 195 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
| 192 | u16 msg_flags, struct ecryptfs_daemon *daemon) | 196 | u16 msg_flags, struct ecryptfs_daemon *daemon) |
| 193 | { | 197 | { |
| 194 | int rc = 0; | 198 | struct ecryptfs_message *msg; |
| 195 | 199 | ||
| 196 | mutex_lock(&msg_ctx->mux); | 200 | msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL); |
| 197 | msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), | 201 | if (!msg) { |
| 198 | GFP_KERNEL); | ||
| 199 | if (!msg_ctx->msg) { | ||
| 200 | rc = -ENOMEM; | ||
| 201 | printk(KERN_ERR "%s: Out of memory whilst attempting " | 202 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
| 202 | "to kmalloc(%zd, GFP_KERNEL)\n", __func__, | 203 | "to kmalloc(%zd, GFP_KERNEL)\n", __func__, |
| 203 | (sizeof(*msg_ctx->msg) + data_size)); | 204 | (sizeof(*msg) + data_size)); |
| 204 | goto out_unlock; | 205 | return -ENOMEM; |
| 205 | } | 206 | } |
| 207 | |||
| 208 | mutex_lock(&msg_ctx->mux); | ||
| 209 | msg_ctx->msg = msg; | ||
| 206 | msg_ctx->msg->index = msg_ctx->index; | 210 | msg_ctx->msg->index = msg_ctx->index; |
| 207 | msg_ctx->msg->data_len = data_size; | 211 | msg_ctx->msg->data_len = data_size; |
| 208 | msg_ctx->type = msg_type; | 212 | msg_ctx->type = msg_type; |
| 209 | memcpy(msg_ctx->msg->data, data, data_size); | 213 | memcpy(msg_ctx->msg->data, data, data_size); |
| 210 | msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); | 214 | msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); |
| 211 | mutex_lock(&daemon->mux); | ||
| 212 | list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); | 215 | 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); | ||
| 213 | daemon->num_queued_msg_ctx++; | 219 | daemon->num_queued_msg_ctx++; |
| 214 | wake_up_interruptible(&daemon->wait); | 220 | wake_up_interruptible(&daemon->wait); |
| 215 | mutex_unlock(&daemon->mux); | 221 | mutex_unlock(&daemon->mux); |
| 216 | out_unlock: | 222 | |
| 217 | mutex_unlock(&msg_ctx->mux); | 223 | return 0; |
| 218 | return rc; | ||
| 219 | } | 224 | } |
| 220 | 225 | ||
| 221 | /* | 226 | /* |
| @@ -269,8 +274,16 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | |||
| 269 | mutex_lock(&ecryptfs_daemon_hash_mux); | 274 | mutex_lock(&ecryptfs_daemon_hash_mux); |
| 270 | /* TODO: Just use file->private_data? */ | 275 | /* TODO: Just use file->private_data? */ |
| 271 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 276 | 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 | } | ||
| 273 | mutex_lock(&daemon->mux); | 281 | 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 | } | ||
| 274 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 287 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
| 275 | rc = 0; | 288 | rc = 0; |
| 276 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 289 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
| @@ -307,9 +320,6 @@ check_list: | |||
| 307 | * message from the queue; try again */ | 320 | * message from the queue; try again */ |
| 308 | goto check_list; | 321 | goto check_list; |
| 309 | } | 322 | } |
| 310 | BUG_ON(euid != daemon->euid); | ||
| 311 | BUG_ON(current_user_ns() != daemon->user_ns); | ||
| 312 | BUG_ON(task_pid(current) != daemon->pid); | ||
| 313 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, | 323 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, |
| 314 | struct ecryptfs_msg_ctx, daemon_out_list); | 324 | struct ecryptfs_msg_ctx, daemon_out_list); |
| 315 | BUG_ON(!msg_ctx); | 325 | BUG_ON(!msg_ctx); |
