git: 768f6373eb3d - main - Fix compat10 semaphore interface race
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 26 Aug 2022 17:34:55 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=768f6373eb3d60e346d3bfa495e04315aeed8ff9 commit 768f6373eb3d60e346d3bfa495e04315aeed8ff9 Author: firk <firk@cantconnect.ru> AuthorDate: 2022-08-26 08:05:56 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2022-08-26 17:34:29 +0000 Fix compat10 semaphore interface race Wrong has-waiters and missing unconditional _count==0 check may cause infinite waiting with already non-zero count. 1) properly clear _has_waiters flag when waiting failed to start 2) always check _count before start waiting PR: 265997 Reviewed by: kib MFC after: 1 week Differential revision: https://reviews.freebsd.org/D36272 --- sys/kern/kern_umtx.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index c8307fb337c2..6b4e3ca38d03 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -3547,24 +3547,28 @@ again: umtxq_insert(uq); umtxq_unlock(&uq->uq_key); rv = casueword32(&sem->_has_waiters, 0, &count1, 1); - if (rv == 0) + if (rv != -1) rv1 = fueword32(&sem->_count, &count); - if (rv == -1 || (rv == 0 && (rv1 == -1 || count != 0)) || - (rv == 1 && count1 == 0)) { + if (rv == -1 || rv1 == -1 || count != 0 || (rv == 1 && count1 == 0)) { + if (rv == 0) + suword32(&sem->_has_waiters, 0); umtxq_lock(&uq->uq_key); umtxq_unbusy(&uq->uq_key); umtxq_remove(uq); umtxq_unlock(&uq->uq_key); - if (rv == 1) { - rv = thread_check_susp(td, true); - if (rv == 0) - goto again; - error = rv; + if (rv == -1 || rv1 == -1) { + error = EFAULT; + goto out; + } + if (count != 0) { + error = 0; goto out; } + MPASS(rv == 1 && count1 == 0); + rv = thread_check_susp(td, true); if (rv == 0) - rv = rv1; - error = rv == -1 ? EFAULT : 0; + goto again; + error = rv; goto out; } umtxq_lock(&uq->uq_key);