race in ipc/msg.c?

Manfred Spraul (manfreds@colorfullife.com)
Mon, 27 Sep 1999 14:21:46 +0000


real_sndmsg() contains a possible race:
[the function runs with the big kernel lock acquired, no other
synchonization]
the function first check the permissions, then it checks that there is
enough free space in the queue available,
linux/ipc/msg.c:
> slept:
> if (msq->msg_perm.seq != (unsigned int) msqid / MSGMNI)
> return -EIDRM;
>
> if (ipcperms(ipcp, S_IWUGO))
> return -EACCES;
>
> if (msgsz + msq->msg_cbytes > msq->msg_qbytes) {
> if (msgsz + msq->msg_cbytes > msq->msg_qbytes) {
> /* still no space in queue */
> if (msgflg & IPC_NOWAIT)
> return -EAGAIN;
> if (signal_pending(current))
> return -EINTR;
> interruptible_sleep_on (&msq->wwait);
> goto slept;
> }
> }

then it kmalloc() the memory for the message and copies the data from
user space into the kernel structure:
> /* allocate message header and text space*/
> msgh = (struct msg *) kmalloc (sizeof(*msgh) + msgsz, GFP_KERNEL);
> if (!msgh)
> return -ENOMEM;
> msgh->msg_spot = (char *) (msgh + 1);
>
> if (copy_from_user(msgh->msg_spot, msgp->mtext, msgsz))
> {
> kfree(msgh);
> return -EFAULT;
> }

Both kmalloc() and copy_from_user() could sleep.
I think this is a bug.

Has anyone tried to replace the current shm implementation with a
deserialized one, ie without the lock_kernel() calls?

--
	Manfred

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/