Re: ipc-msg broken again on 3.11-rc7?

From: Manfred Spraul
Date: Tue Sep 03 2013 - 06:17:04 EST


Hi Vineet,

On 09/03/2013 11:51 AM, Vineet Gupta wrote:
On 09/03/2013 02:53 PM, Manfred Spraul wrote:

The access to msq->q_cbytes is not protected.

Vineet, could you try to move the test for free space after ipc_lock?
I.e. the lock must not get dropped between testing for free space and
enqueueing the messages.
Hmm, the code movement is not trivial. I broke even the simplest of cases (patch
attached). This includes the additional change which Linus/Davidlohr had asked for.
The attached patch should work. Could you try it?

--
Manfred
diff --git a/ipc/msg.c b/ipc/msg.c
index 9f29d9e..b65fdf1 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -680,16 +680,18 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
goto out_unlock1;
}

+ ipc_lock_object(&msq->q_perm);
+
for (;;) {
struct msg_sender s;

err = -EACCES;
if (ipcperms(ns, &msq->q_perm, S_IWUGO))
- goto out_unlock1;
+ goto out_unlock0;

err = security_msg_queue_msgsnd(msq, msg, msgflg);
if (err)
- goto out_unlock1;
+ goto out_unlock0;

if (msgsz + msq->q_cbytes <= msq->q_qbytes &&
1 + msq->q_qnum <= msq->q_qbytes) {
@@ -699,10 +701,9 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
/* queue full, wait: */
if (msgflg & IPC_NOWAIT) {
err = -EAGAIN;
- goto out_unlock1;
+ goto out_unlock0;
}

- ipc_lock_object(&msq->q_perm);
ss_add(msq, &s);

if (!ipc_rcu_getref(msq)) {
@@ -730,10 +731,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
goto out_unlock0;
}

- ipc_unlock_object(&msq->q_perm);
}
-
- ipc_lock_object(&msq->q_perm);
msq->q_lspid = task_tgid_vnr(current);
msq->q_stime = get_seconds();