From nobody Tue Dec 10 20:03:18 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 4Y78mk5KFFz5gYks; Tue, 10 Dec 2024 20:03:18 +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 4Y78mk4HJyz4Nr1; Tue, 10 Dec 2024 20:03:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733860998; 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=AmERC/ROs/cXMyLlNp4Q2uRho8WZUx1rm4A2n+Rn2x0=; b=eCEQ+SBNFwnJVB/YUV2mKrfnV2PReu+fFMOzTC91A/KUncqnJtqpWGHUIkTzfmTLkx9Weg 35RWGPoqXQuiBYmcrgmJWox6MRyZJZY0jfb3Z5zoCaWWfW3aXFxM9D4DyDENI2aSUk+OmW bD4KGKXoRyz0TXTLo3XTabEvl8QEXoZyRjvUYoRO3FxJM34tOmosoxVJXBSPtS89SGRPPk 4HkzqV/DBS/owR3E62K+/cTIp5qPGDZIOWHkM5xuISb0a3ts1YlHDgIqJ6h3FPMjCbUWib WYU2n3HBB6PUj+f8UjlkTXNPP5SpG/ZOFFhEXDVTFK9LrDsiw2VmVEg/obfIKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733860998; 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=AmERC/ROs/cXMyLlNp4Q2uRho8WZUx1rm4A2n+Rn2x0=; b=YscHf7GQUmd/dZtoJwgK09uVBrVTNrKBJTyVvF+L9MMP3fNu8Tt0Yr0j0Ia+LDHiprOS7I UTIXe9zirQB7E82a5R7kii1rskBDCoDRHzBKAfCM8sk9h5AfWlxgsGqrDRMzmAnBj30mb5 FOVrhYwTlSle+u4z7Elqbpapi/zCAMwJXcUFE54FbuGSuenFop/FJ0YKt7LpZwjYcYMnEw zO51BNZmirmh403dIJzGCO+pAQalQvVSi4jiMhcA2ENeic+kYViE01cM1iEDSsNkBPcdkN RuOUQZsFFnUVMhHsOSQHwaCOkJOzS1VMdNKlubQsqJ3I8mgzRsEXpEYqfWasTw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1733860998; a=rsa-sha256; cv=none; b=R80paqqstYfVe6vOH5bh4aO0qcemAy7tNocyhiZbnn9qXa8W5n0/Iu7umr5n0VyKjEf1DK nlhG1jLx8XvZVrgxSGixibqu6ty4GS1vpd4tSnvalZlsx9P0cZIGlo7Ei6Qiqf/an54AAG a73P+Ae9L7N2iKtydWBhr75x97I7OXOUomttTjwXqFAfN4rFh75qwP97CjxRuT5Rh0Ko+Y iGrnzLuF00/PTv4QspkGmsuHEakFKeV9PDod8ch+UtRlMMbnCeAGdcsnGqgGzhnrkeXXHG 2CDMdPdVZIRfb9nhNa/lAicHtXo9HBLpsBLoPm03GFHu+usm+xjJBk7Mc/EiZg== 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 4Y78mk3ts0zd9M; Tue, 10 Dec 2024 20:03:18 +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 4BAK3IBP028334; Tue, 10 Dec 2024 20:03:18 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BAK3IB7028331; Tue, 10 Dec 2024 20:03:18 GMT (envelope-from git) Date: Tue, 10 Dec 2024 20:03:18 GMT Message-Id: <202412102003.4BAK3IB7028331@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: c4290f346662 - stable/14 - 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/14 X-Git-Reftype: branch X-Git-Commit: c4290f3466624f8e26af83f3090c3b0f62512ca1 Auto-Submitted: auto-generated The branch stable/14 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=c4290f3466624f8e26af83f3090c3b0f62512ca1 commit c4290f3466624f8e26af83f3090c3b0f62512ca1 Author: Kyle Evans AuthorDate: 2024-11-26 04:04:48 +0000 Commit: Kyle Evans CommitDate: 2024-12-10 20:02:52 +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. (cherry picked from commit ccb973da1f1b65879eade8e65cdd2885e125f90e) --- sys/kern/sys_generic.c | 53 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 77e4c13d4390..6a80ddbe86ed 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1050,15 +1050,31 @@ 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. */ - ast_sched(td, TDA_SIGSUSPEND); + if (error == EINTR) { + td->td_pflags |= TDP_OLDMASK; + ast_sched(td, TDA_SIGSUSPEND); + } 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); } @@ -1529,13 +1545,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. - */ - ast_sched(td, TDA_SIGSUSPEND); } seltdinit(td); @@ -1558,6 +1567,28 @@ 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; + ast_sched(td, TDA_SIGSUSPEND); + } else { + int serror __diagused; + + serror = kern_sigprocmask(td, SIG_SETMASK, + &td->td_oldsigmask, NULL, 0); + MPASS(serror == 0); + } + } + return (error); }