Commit b06d7b4c authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] security bugfix for mqueue

From: Manfred Spraul <manfred@colorfullife.com>

I found a security bug in the new mqueue code: a process that has only
write permissions to a message queue could call mq_notify(SIGEV_THREAD) and
use the returned notification file descriptor to read from the message
queue.
parent f3ca8d5d
...@@ -836,11 +836,11 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, ...@@ -836,11 +836,11 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
goto out; goto out;
inode = filp->f_dentry->d_inode; inode = filp->f_dentry->d_inode;
if (unlikely(inode->i_sb != mqueue_mnt->mnt_sb)) if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput; goto out_fput;
info = MQUEUE_I(inode); info = MQUEUE_I(inode);
if (unlikely((filp->f_flags & O_ACCMODE) == O_RDONLY)) if (unlikely(!(filp->f_mode & FMODE_WRITE)))
goto out_fput; goto out_fput;
if (unlikely(msg_len > info->attr.mq_msgsize)) { if (unlikely(msg_len > info->attr.mq_msgsize)) {
...@@ -915,11 +915,11 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, ...@@ -915,11 +915,11 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
goto out; goto out;
inode = filp->f_dentry->d_inode; inode = filp->f_dentry->d_inode;
if (unlikely(inode->i_sb != mqueue_mnt->mnt_sb)) if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput; goto out_fput;
info = MQUEUE_I(inode); info = MQUEUE_I(inode);
if (unlikely((filp->f_flags & O_ACCMODE) == O_WRONLY)) if (unlikely(!(filp->f_mode & FMODE_READ)))
goto out_fput; goto out_fput;
/* checks if buffer is big enough */ /* checks if buffer is big enough */
...@@ -1008,7 +1008,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes, ...@@ -1008,7 +1008,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
goto out; goto out;
inode = filp->f_dentry->d_inode; inode = filp->f_dentry->d_inode;
if (unlikely(inode->i_sb != mqueue_mnt->mnt_sb)) if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput; goto out_fput;
info = MQUEUE_I(inode); info = MQUEUE_I(inode);
...@@ -1028,6 +1028,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes, ...@@ -1028,6 +1028,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
nfilp->f_vfsmnt = mntget(mqueue_mnt); nfilp->f_vfsmnt = mntget(mqueue_mnt);
nfilp->f_dentry = dget(filp->f_dentry); nfilp->f_dentry = dget(filp->f_dentry);
nfilp->f_mapping = filp->f_dentry->d_inode->i_mapping; nfilp->f_mapping = filp->f_dentry->d_inode->i_mapping;
nfilp->f_flags = O_RDONLY;
nfilp->f_mode = FMODE_READ; nfilp->f_mode = FMODE_READ;
} else { } else {
nfilp = NULL; nfilp = NULL;
...@@ -1092,7 +1093,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes, ...@@ -1092,7 +1093,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
goto out; goto out;
inode = filp->f_dentry->d_inode; inode = filp->f_dentry->d_inode;
if (unlikely(inode->i_sb != mqueue_mnt->mnt_sb)) if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput; goto out_fput;
info = MQUEUE_I(inode); info = MQUEUE_I(inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment