From d9428e8708b10c857f1678635157662189cb10eb Mon Sep 17 00:00:00 2001 From: Manfred Spraul Date: Tue, 25 Oct 2011 02:00:05 +1100 Subject: [PATCH] ipc/sem.c: fix return code race with semop vs. semop +semctl(IPC_RMID) sys_semtimedop() may return -EIDRM although the semaphore operation completed successfully: thread 1: thread 2: semtimedop(), sleeps semop(): * acquires sem_lock() semtimedop() woken up due to timeout sem_lock() loops * notices that thread 2 could be completed. * performs the operations that thread 2 is sleeping on. * marks the semaphore operation as IN_WAKEUP * drops sem_lock(), does wakeup, sets return code to 0 * thread delayed due to interrupt, whatever * returns to user space * thread still delayed semctl(IPC_RMID) * acquires sem_lock() * ipc_rmid(), ipcp->deleted=1 * drops sem_lock() * thread finally continues - but seem_lock() now fails due to ipcp->deleted == 1 * returns -EIDRM instead of 0 The fix is trivial: Always use the return code in queue.status. In real world, the race probably doesn't matter: If the semaphore array is destroyed, the app is probably not interested if the last operation succeeded or was already cancelled. Signed-off-by: Manfred Spraul Cc: Thomas Gleixner Cc: Mike Galbraith Acked-by: Peter Zijlstra Signed-off-by: Andrew Morton --- ipc/sem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ipc/sem.c b/ipc/sem.c index c8e00f8b4be1..fb13be17945b 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -1460,7 +1460,6 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, * Array removed? If yes, leave without sem_unlock(). */ if (IS_ERR(sma)) { - error = -EIDRM; goto out_free; } -- 2.39.5