Module Name: src Committed By: riastradh Date: Mon Apr 27 23:54:43 UTC 2020
Modified Files: src/sys/kern: sys_futex.c Log Message: Fix races in aborted futex waits. - Re-check the wake condition in futex_wait in the event of error. => Otherwise, if futex_wait times out in cv_timedwait_sig but futex_wake wakes it while cv_timedwait_sig is still trying to reacquire fw_lock, the wake would be incorrectly accounted. - Fold futex_wait_abort into futex_wait so it happens atomically. => Otherwise, if futex_wait times out and release fw_lock, then, before futex_wait_abort reacquires the lock and removes it from the queue, the waiter could be woken by futex_wake. But once we enter futex_wait_abort, the decision to abort is final, so the wake would incorrectly accounted. - In futex_wait_abort, mark each waiter aborting while we do the lock dance, and skip over aborting waiters in futex_wake and futex_requeue. => Otherwise, futex_wake might move it to a new futex while futex_wait_abort has released all the locks -- but futex_wait_abort still has the old futex, so TAILQ_REMOVE will cross the streams and bad things will happen. - In futex_wait_abort, release the futex we moved the waiter off. => Otherwise, we would leak the futex reference acquired by futex_func_wait, in the event of aborting. (For normal wakeups, futex_wake releases the reference on our behalf.) - Consistently use futex_wait_dequeue rather than TAILQ_REMOVE so that all changes to fw_futex and the waiter queue are isolated to futex_wait_enqueue/dequeue and happen together. Patch developed with and tested by thorpej@. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/kern/sys_futex.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.