• Manfred Spraul's avatar
    ipc/sem.c: fix return code race with semop vs. semop +semctl(IPC_RMID) · 3c24783b
    Manfred Spraul authored
    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: default avatarManfred Spraul <manfred@colorfullife.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Mike Galbraith <efault@gmx.de>
    Acked-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    3c24783b
sem.c 40.4 KB