From owner-dev-commits-src-all@freebsd.org Fri Mar 12 18:34:37 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9BEB35A980F; Fri, 12 Mar 2021 18:34:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DxvcF44VZz4hTt; Fri, 12 Mar 2021 18:34:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7E6A51C534; Fri, 12 Mar 2021 18:34:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 12CIYbrh032455; Fri, 12 Mar 2021 18:34:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 12CIYbIJ032454; Fri, 12 Mar 2021 18:34:37 GMT (envelope-from git) Date: Fri, 12 Mar 2021 18:34:37 GMT Message-Id: <202103121834.12CIYbIJ032454@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Jonathan T. Looney" Subject: git: dbec10e08808 - main - Fetch the sigfastblock value in syscalls that wait for signals MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jtl X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: dbec10e08808e375365fb2a2462f306e0cdfda32 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Mar 2021 18:34:37 -0000 The branch main has been updated by jtl: URL: https://cgit.FreeBSD.org/src/commit/?id=dbec10e08808e375365fb2a2462f306e0cdfda32 commit dbec10e08808e375365fb2a2462f306e0cdfda32 Author: Jonathan T. Looney AuthorDate: 2021-03-12 18:14:17 +0000 Commit: Jonathan T. Looney CommitDate: 2021-03-12 18:14:17 +0000 Fetch the sigfastblock value in syscalls that wait for signals We have seen several cases of processes which have become "stuck" in kern_sigsuspend(). When this occurs, the kernel's td_sigblock_val is set to 0x10 (one block outstanding) and the userspace copy of the word is set to 0 (unblocked). Because the kernel's cached value shows that signals are blocked, kern_sigsuspend() blocks almost all signals, which means the process hangs indefinitely in sigsuspend(). It is not entirely clear what is causing this condition to occur. However, it seems to make sense to add some protection against this case by fetching the latest sigfastblock value from userspace for syscalls which will sleep waiting for signals. Here, the change is applied to kern_sigsuspend() and kern_sigtimedwait(). Reviewed by: kib Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D29225 --- sys/kern/kern_sig.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 7884b5be9f91..3d55405d3151 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1268,6 +1268,9 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi, ets.tv_nsec = 0; traced = false; + /* Ensure the sigfastblock value is up to date. */ + sigfastblock_fetch(td); + if (timeout != NULL) { if (timeout->tv_nsec >= 0 && timeout->tv_nsec < 1000000000) { timevalid = 1; @@ -1527,6 +1530,9 @@ kern_sigsuspend(struct thread *td, sigset_t mask) struct proc *p = td->td_proc; int has_sig, sig; + /* Ensure the sigfastblock value is up to date. */ + sigfastblock_fetch(td); + /* * When returning from sigsuspend, we want * the old mask to be restored after the