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

Changed files
+30 -20
fs
ecryptfs
+1 -1
fs/ecryptfs/kthread.c
··· 149 149 (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred); 150 150 if (!IS_ERR(*lower_file)) 151 151 goto out; 152 - if (flags & O_RDONLY) { 152 + if ((flags & O_ACCMODE) == O_RDONLY) { 153 153 rc = PTR_ERR((*lower_file)); 154 154 goto out; 155 155 }
+29 -19
fs/ecryptfs/miscdev.c
··· 49 49 mutex_lock(&ecryptfs_daemon_hash_mux); 50 50 /* TODO: Just use file->private_data? */ 51 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 56 mutex_lock(&daemon->mux); 54 57 mutex_unlock(&ecryptfs_daemon_hash_mux); 55 58 if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { ··· 125 122 goto out_unlock_daemon; 126 123 } 127 124 daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; 125 + file->private_data = daemon; 128 126 atomic_inc(&ecryptfs_num_miscdev_opens); 129 127 out_unlock_daemon: 130 128 mutex_unlock(&daemon->mux); ··· 156 152 157 153 mutex_lock(&ecryptfs_daemon_hash_mux); 158 154 rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); 159 - BUG_ON(rc || !daemon); 155 + if (rc || !daemon) 156 + daemon = file->private_data; 160 157 mutex_lock(&daemon->mux); 161 - BUG_ON(daemon->pid != task_pid(current)); 162 158 BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); 163 159 daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; 164 160 atomic_dec(&ecryptfs_num_miscdev_opens); ··· 195 191 struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, 196 192 u16 msg_flags, struct ecryptfs_daemon *daemon) 197 193 { 198 - int rc = 0; 194 + struct ecryptfs_message *msg; 199 195 200 - mutex_lock(&msg_ctx->mux); 201 - msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), 202 - GFP_KERNEL); 203 - if (!msg_ctx->msg) { 204 - rc = -ENOMEM; 196 + msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL); 197 + if (!msg) { 205 198 printk(KERN_ERR "%s: Out of memory whilst attempting " 206 199 "to kmalloc(%zd, GFP_KERNEL)\n", __func__, 207 - (sizeof(*msg_ctx->msg) + data_size)); 208 - goto out_unlock; 200 + (sizeof(*msg) + data_size)); 201 + return -ENOMEM; 209 202 } 203 + 204 + mutex_lock(&msg_ctx->mux); 205 + msg_ctx->msg = msg; 210 206 msg_ctx->msg->index = msg_ctx->index; 211 207 msg_ctx->msg->data_len = data_size; 212 208 msg_ctx->type = msg_type; 213 209 memcpy(msg_ctx->msg->data, data, data_size); 214 210 msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); 215 - mutex_lock(&daemon->mux); 216 211 list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); 212 + mutex_unlock(&msg_ctx->mux); 213 + 214 + mutex_lock(&daemon->mux); 217 215 daemon->num_queued_msg_ctx++; 218 216 wake_up_interruptible(&daemon->wait); 219 217 mutex_unlock(&daemon->mux); 220 - out_unlock: 221 - mutex_unlock(&msg_ctx->mux); 222 - return rc; 218 + 219 + return 0; 223 220 } 224 221 225 222 /* ··· 274 269 mutex_lock(&ecryptfs_daemon_hash_mux); 275 270 /* TODO: Just use file->private_data? */ 276 271 rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); 277 - BUG_ON(rc || !daemon); 272 + if (rc || !daemon) { 273 + mutex_unlock(&ecryptfs_daemon_hash_mux); 274 + return -EINVAL; 275 + } 278 276 mutex_lock(&daemon->mux); 277 + if (task_pid(current) != daemon->pid) { 278 + mutex_unlock(&daemon->mux); 279 + mutex_unlock(&ecryptfs_daemon_hash_mux); 280 + return -EPERM; 281 + } 279 282 if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { 280 283 rc = 0; 281 284 mutex_unlock(&ecryptfs_daemon_hash_mux); ··· 320 307 * message from the queue; try again */ 321 308 goto check_list; 322 309 } 323 - BUG_ON(euid != daemon->euid); 324 - BUG_ON(current_user_ns() != daemon->user_ns); 325 - BUG_ON(task_pid(current) != daemon->pid); 326 310 msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, 327 311 struct ecryptfs_msg_ctx, daemon_out_list); 328 312 BUG_ON(!msg_ctx);