diff options
author | Andrew Morton <akpm@osdl.org> | 2004-04-11 22:55:07 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-04-11 22:55:07 -0700 |
commit | b06d7b4c9bc34dd377d54acb7c9beae36d5f745c (patch) | |
tree | 233eba4641a61b86365cf5826cf3646651a0bca9 /ipc | |
parent | f3ca8d5dd5c23594bda07893ae374bed7981d473 (diff) | |
download | history-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.c | 13 |
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); |