<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Manfred Spraul &lt;manfred@colorfullife.com&gt;

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	Wed Apr  7 12:12:48 2004
+++ 25-akpm/ipc/mqueue.c	Wed Apr  7 12:12:48 2004
@@ -837,11 +837,11 @@ asmlinkage long sys_mq_timedsend(mqd_t m
 		goto out;
 
 	inode = filp-&gt;f_dentry-&gt;d_inode;
-	if (unlikely(inode-&gt;i_sb != mqueue_mnt-&gt;mnt_sb))
+	if (unlikely(filp-&gt;f_op != &amp;mqueue_file_operations))
 		goto out_fput;
 	info = MQUEUE_I(inode);
 
-	if (unlikely((filp-&gt;f_flags &amp; O_ACCMODE) == O_RDONLY))
+	if (unlikely(!(filp-&gt;f_mode &amp; FMODE_WRITE)))
 		goto out_fput;
 
 	if (unlikely(msg_len &gt; info-&gt;attr.mq_msgsize)) {
@@ -915,11 +915,11 @@ asmlinkage ssize_t sys_mq_timedreceive(m
 		goto out;
 
 	inode = filp-&gt;f_dentry-&gt;d_inode;
-	if (unlikely(inode-&gt;i_sb != mqueue_mnt-&gt;mnt_sb))
+	if (unlikely(filp-&gt;f_op != &amp;mqueue_file_operations))
 		goto out_fput;
 	info = MQUEUE_I(inode);
 
-	if (unlikely((filp-&gt;f_flags &amp; O_ACCMODE) == O_WRONLY))
+	if (unlikely(!(filp-&gt;f_mode &amp; 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-&gt;f_dentry-&gt;d_inode;
-	if (unlikely(inode-&gt;i_sb != mqueue_mnt-&gt;mnt_sb))
+	if (unlikely(filp-&gt;f_op != &amp;mqueue_file_operations))
 		goto out_fput;
 	info = MQUEUE_I(inode);
 
@@ -1024,6 +1024,7 @@ asmlinkage long sys_mq_notify(mqd_t mqde
 		nfilp-&gt;f_vfsmnt = mntget(mqueue_mnt);
 		nfilp-&gt;f_dentry = dget(filp-&gt;f_dentry);
 		nfilp-&gt;f_mapping = filp-&gt;f_dentry-&gt;d_inode-&gt;i_mapping;
+		nfilp-&gt;f_flags = O_RDONLY;
 		nfilp-&gt;f_mode = FMODE_READ;
 	} else {
 		nfilp = NULL;
@@ -1088,7 +1089,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t 
 		goto out;
 
 	inode = filp-&gt;f_dentry-&gt;d_inode;
-	if (unlikely(inode-&gt;i_sb != mqueue_mnt-&gt;mnt_sb))
+	if (unlikely(filp-&gt;f_op != &amp;mqueue_file_operations))
 		goto out_fput;
 	info = MQUEUE_I(inode);
 

_
</pre></body></html>