aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-04-11 22:55:07 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-11 22:55:07 -0700
commitb06d7b4c9bc34dd377d54acb7c9beae36d5f745c (patch)
tree233eba4641a61b86365cf5826cf3646651a0bca9 /ipc
parentf3ca8d5dd5c23594bda07893ae374bed7981d473 (diff)
downloadhistory-b06d7b4c9bc34dd377d54acb7c9beae36d5f745c.tar.gz
[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.
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index b5f731781f56f2..f0d78fefc28bfa 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -836,11 +836,11 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
goto out;
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;
info = MQUEUE_I(inode);
- if (unlikely((filp->f_flags & O_ACCMODE) == O_RDONLY))
+ if (unlikely(!(filp->f_mode & FMODE_WRITE)))
goto out_fput;
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,
goto out;
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;
info = MQUEUE_I(inode);
- if (unlikely((filp->f_flags & O_ACCMODE) == O_WRONLY))
+ if (unlikely(!(filp->f_mode & FMODE_READ)))
goto out_fput;
/* checks if buffer is big enough */
@@ -1008,7 +1008,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
goto out;
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;
info = MQUEUE_I(inode);
@@ -1028,6 +1028,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
nfilp->f_vfsmnt = mntget(mqueue_mnt);
nfilp->f_dentry = dget(filp->f_dentry);
nfilp->f_mapping = filp->f_dentry->d_inode->i_mapping;
+ nfilp->f_flags = O_RDONLY;
nfilp->f_mode = FMODE_READ;
} else {
nfilp = NULL;
@@ -1092,7 +1093,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
goto out;
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;
info = MQUEUE_I(inode);