The branch stable/13 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7e8fa3c9a2102cff1a76cc74c4c739e039c59d23

commit 7e8fa3c9a2102cff1a76cc74c4c739e039c59d23
Author:     firk <[email protected]>
AuthorDate: 2022-08-26 08:05:56 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2022-08-31 01:20:29 +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 513b084ea489..6aac9f3311d6 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -3513,24 +3513,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);

Reply via email to