Just as with msgrcv (along with the rest of sysvipc since a few
years ago), perform the security checks without holding the ipc
object lock. This also reduces the hogging of the lock for the
entire duration of a sender, as we drop the lock upon every
iteration -- and this is exactly why we also check for racing
with RMID in the first place.

Signed-off-by: Davidlohr Bueso <dbu...@suse.de>
---
 ipc/msg.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/ipc/msg.c b/ipc/msg.c
index 5181259e2ff0..fe793304dddb 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -623,14 +623,14 @@ 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_unlock0;
+                       goto out_unlock1;
+
+               ipc_lock_object(&msq->q_perm);
 
                /* raced with RMID? */
                if (!ipc_valid_object(&msq->q_perm)) {
@@ -681,6 +681,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
                        goto out_unlock0;
                }
 
+               ipc_unlock_object(&msq->q_perm);
        }
        msq->q_lspid = task_tgid_vnr(current);
        msq->q_stime = get_seconds();
-- 
2.6.6

Reply via email to