git: 3e39cbb10e0d - stable/12 - Fix compat10 semaphore interface race

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 31 Aug 2022 01:33:58 UTC
The branch stable/12 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=3e39cbb10e0d4cf9db17ac38a0cca39aa3c5e403

commit 3e39cbb10e0d4cf9db17ac38a0cca39aa3c5e403
Author:     firk <firk@cantconnect.ru>
AuthorDate: 2022-08-26 08:05:56 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-08-31 01:33:38 +0000

    Fix compat10 semaphore interface race
    
    PR:     265997
    
    (cherry picked from commit 768f6373eb3d60e346d3bfa495e04315aeed8ff9)
---
 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 be427c9b3b54..956da51f8a07 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -3182,24 +3182,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);