Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Aug 2021 00:43:06 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 48edac83b3b5 - stable/13 - sigtimedwait: Use a unique wait channel for sleeping
Message-ID:  <202108230043.17N0h65e075937@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=48edac83b3b577c2864f8ea4f8bb9962c834eaf8

commit 48edac83b3b577c2864f8ea4f8bb9962c834eaf8
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-08-16 17:15:25 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-08-23 00:42:56 +0000

    sigtimedwait: Use a unique wait channel for sleeping
    
    When a sigtimedwait(2) caller goes to sleep, it uses a wait channel of
    p->p_sigacts with the proc lock as the interlock.  However, p_sigacts
    can be shared between processes if a child is created with
    rfork(RFSIGSHARE | RFPROC).  Thus we can end up with two threads
    sleeping on the same wait channel using different locks, which is not
    permitted.
    
    Fix the problem simply by using a process-unique wait channel, following
    the example of sigsuspend.  The actual wait channel value is irrelevant
    here, sleeping threads are awoken using sleepq_abort().
    
    Reported by:    syzbot+8c417afabadb50bb8827@syzkaller.appspotmail.com
    Reported by:    syzbot+1d89fc2a9ef92ef64fa8@syzkaller.appspotmail.com
    Reviewed by:    kib
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit c4feb1ab0ae0c0e779af372e4c5f3b9e0d3e1388)
---
 sys/kern/kern_sig.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 4f6f424fb05d..d61812ad3043 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1341,7 +1341,8 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi,
 			break;
 		}
 
-		error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", timo);
+		error = msleep(&p->p_sigacts, &p->p_mtx, PPAUSE | PCATCH,
+		    "sigwait", timo);
 
 		/* The syscalls can not be restarted. */
 		if (error == ERESTART)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108230043.17N0h65e075937>