Use ERESTART for any single_thread_set() error in sys_execve().
authorclaudio <claudio@openbsd.org>
Mon, 30 Oct 2023 07:13:10 +0000 (07:13 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 30 Oct 2023 07:13:10 +0000 (07:13 +0000)
If single thread is already held by another thread just unwind to userret()
wait there and retry the system call later (if at all).
OK mpi@

sys/kern/kern_exec.c

index a85010d..9d8ec98 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exec.c,v 1.251 2023/09/29 12:47:34 claudio Exp $ */
+/*     $OpenBSD: kern_exec.c,v 1.252 2023/10/30 07:13:10 claudio Exp $ */
 /*     $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $  */
 
 /*-
@@ -283,9 +283,12 @@ sys_execve(struct proc *p, void *v, register_t *retval)
                return (0);
        }
 
-       /* get other threads to stop */
-       if ((error = single_thread_set(p, SINGLE_UNWIND | SINGLE_DEEP)))
-               return (error);
+       /*
+        * Get other threads to stop, if contested return ERESTART,
+        * so the syscall is restarted after halting in userret.
+        */
+       if (single_thread_set(p, SINGLE_UNWIND | SINGLE_DEEP))
+               return (ERESTART);
 
        /*
         * Cheap solution to complicated problems.