From nobody Tue Dec 10 20:03:23 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Y78mq2qccz5gYWR; Tue, 10 Dec 2024 20:03:23 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Y78mq25Lvz4P7c; Tue, 10 Dec 2024 20:03:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733861003; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=IWtf46lo6/oLuGbqgo5ba+aYdhHU9f9ZH5anuVwHsDs=; b=DsaXRDxiJINBrDM0sInh//G3Hou/nhdqZ0jDho1vQ86uRrd9qoF+IMUEyEWvn50IXm6dsF XMnwhShxH6HC5vNlX2BQBx9qqVDmXAD6QYzkI5CuUOdY1HN6kS0m4idOQcvL8lPqySPKlq lW+ZnQ6DO+nvANv4suTupDzt6lyFaScsxQGc8QRmtd6xKAYvclrjtZg0xwjtLQBzfJfw++ HSP/U6RiJEnGxZu5gb77JKHFGvcvyUMLOBGr8U8b9IMkp5OSrfHuUAx2pFYDwLY5TvjdB0 gAWN0V5e9A87CekFLp9j5mfYvEqjZeVrDLCVu3v99RoWh5g8LHMGXOhTRrtiog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733861003; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=IWtf46lo6/oLuGbqgo5ba+aYdhHU9f9ZH5anuVwHsDs=; b=wfsPvUDuVczQvpJ2vtFKh5THCs0Ml7XcuSlmIv4v44l+ZwgTIujPYqW9zDPHybjzpCtNyV zqn9SpUK3jgdC+pjtIYKVV2HDUbG4ruOGJkJTQ8pBB4ikK/TN0wjWLYSWvSIL5q9J8FqFo RqFtEZLEWgMT3SLw0biYJSBN0wwic6d14HSHkDLLMNvxuTZ/pKU3DW1uLnCW2WoWn2UWYb o2U0lB2LzJhtKdr1h7lEW/Ru/0YhuqP+fsKh85ezOTGDMqfnTs0bhb65K0IAfnqr+yYCYQ zYNA4FAeNpLcaYdl4SEHry4yPHyWUWO3E5gPqogo04LLVI7nabWJUY7G2vvi6w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1733861003; a=rsa-sha256; cv=none; b=UHs5Vpn6mEx9f2dn6uEr5RmsjzkSDg3dzxDv2c4vO73nfNYX3p7ESVAJLjf0lfuIrpd5lm eNMZmVial/Q778rR7iMiIytK4rD6LfLzr92tx5/+1fVgD4HFJKO1nWtg/xR9kbgPmvxLbJ CFr0ClzjWlFizMooqi/IUlgmVsjbkJd+JORZBZrvK1hdtevQCYiTj4REp6EarTzWwNLd14 nnlbkPd3bFxxebvQlWl7LW+tgPaaztmTMC0Njk33yoQha9jerAzLzvuY1TLJZiPJmJVp57 YqCA6kh5P3+lLKKA7gA8/y1XzoL7Vo9Sl7nGpowsbWNzLQ4cSM9+aw8bqvB+Dw== 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 4Y78mq1c4DzdCV; Tue, 10 Dec 2024 20:03:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4BAK3NZ3028504; Tue, 10 Dec 2024 20:03:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BAK3NFm028499; Tue, 10 Dec 2024 20:03:23 GMT (envelope-from git) Date: Tue, 10 Dec 2024 20:03:23 GMT Message-Id: <202412102003.4BAK3NFm028499@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: e5e44726d5af - stable/13 - kern: restore signal mask before ast() for pselect/ppoll List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: e5e44726d5afdb260893a3b4e0be025f6dd74bd4 Auto-Submitted: auto-generated The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=e5e44726d5afdb260893a3b4e0be025f6dd74bd4 commit e5e44726d5afdb260893a3b4e0be025f6dd74bd4 Author: Kyle Evans AuthorDate: 2024-11-26 04:04:48 +0000 Commit: Kyle Evans CommitDate: 2024-12-10 20:03:14 +0000 kern: restore signal mask before ast() for pselect/ppoll It's possible to take a signal after pselect/ppoll have set their return value, but before we actually return to userland. This results in taking a signal without reflecting it in the return value, which weakens the guarantees provided by these functions. Switch both to restore the signal mask before we would deliver signals on return to userland. If a signal was received after the wait was over, then we'll just have the signal queued up for the next time it comes unblocked. The modified signal mask is retained if we were interrupted so that ast() actually handles the signal, at which point the signal mask is restored. des@ has a test case demonstrating the issue in D47738 which will follow. Reported by: des Reviewed by: des (earlier version), kib Sponsored by: Klara, Inc. Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D47741 (cherry picked from commit ccb973da1f1b65879eade8e65cdd2885e125f90e) --- sys/kern/sys_generic.c | 61 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index a0a13e77131b..c605e3f00fdd 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -975,17 +975,33 @@ kern_pselect(struct thread *td, int nd, fd_set *in, fd_set *ou, fd_set *ex, &td->td_oldsigmask, 0); if (error != 0) return (error); - td->td_pflags |= TDP_OLDMASK; + } + error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits); + if (uset != NULL) { /* * Make sure that ast() is called on return to * usermode and TDP_OLDMASK is cleared, restoring old - * sigmask. + * sigmask. If we didn't get interrupted, then the caller is + * likely not expecting a signal to hit that should normally be + * blocked by its signal mask, so we restore the mask before + * any signals could be delivered. */ - thread_lock(td); - td->td_flags |= TDF_ASTPENDING; - thread_unlock(td); + if (error == EINTR) { + td->td_pflags |= TDP_OLDMASK; + thread_lock(td); + td->td_flags |= TDF_ASTPENDING; + thread_unlock(td); + } else { + int serror __diagused; + + /* *select(2) should never restart. */ + MPASS(error != ERESTART); + serror = kern_sigprocmask(td, SIG_SETMASK, + &td->td_oldsigmask, NULL, 0); + MPASS(serror == 0); + } } - error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits); + return (error); } @@ -1456,15 +1472,6 @@ kern_poll_kfds(struct thread *td, struct pollfd *kfds, u_int nfds, &td->td_oldsigmask, 0); if (error) return (error); - td->td_pflags |= TDP_OLDMASK; - /* - * Make sure that ast() is called on return to - * usermode and TDP_OLDMASK is cleared, restoring old - * sigmask. - */ - thread_lock(td); - td->td_flags |= TDF_ASTPENDING; - thread_unlock(td); } seltdinit(td); @@ -1487,6 +1494,30 @@ kern_poll_kfds(struct thread *td, struct pollfd *kfds, u_int nfds, error = EINTR; if (error == EWOULDBLOCK) error = 0; + + if (uset != NULL) { + /* + * Make sure that ast() is called on return to + * usermode and TDP_OLDMASK is cleared, restoring old + * sigmask. If we didn't get interrupted, then the caller is + * likely not expecting a signal to hit that should normally be + * blocked by its signal mask, so we restore the mask before + * any signals could be delivered. + */ + if (error == EINTR) { + td->td_pflags |= TDP_OLDMASK; + thread_lock(td); + td->td_flags |= TDF_ASTPENDING; + thread_unlock(td); + } else { + int serror __diagused; + + serror = kern_sigprocmask(td, SIG_SETMASK, + &td->td_oldsigmask, NULL, 0); + MPASS(serror == 0); + } + } + return (error); }