From: Manfred Spraul 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. --- 25-akpm/ipc/mqueue.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff -puN ipc/mqueue.c~mq-security-fix ipc/mqueue.c --- 25/ipc/mqueue.c~mq-security-fix 2004-04-03 02:59:54.095129232 -0800 +++ 25-akpm/ipc/mqueue.c 2004-04-03 02:59:54.099128624 -0800 @@ -837,11 +837,11 @@ asmlinkage long sys_mq_timedsend(mqd_t m 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(m 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 */ @@ -1004,7 +1004,7 @@ asmlinkage long sys_mq_notify(mqd_t mqde 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); @@ -1024,6 +1024,7 @@ asmlinkage long sys_mq_notify(mqd_t mqde 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; @@ -1088,7 +1089,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t 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); _