From nobody Fri Jun 17 19:37:07 2022 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 39C5385A56A; Fri, 17 Jun 2022 19:37:08 +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 4LPq7755QXz3PNj; Fri, 17 Jun 2022 19:37:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655494628; 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=CyrDsSD4tw2p6/UhMCizve2mEbvLdSpNOnsGktE7mbc=; b=qhY9KEoCVC6tn1v2QvWp+5g8bDxiQljsH0en4jGkEzSXKCfaEhyy8SL1P5SJ6tGu+dd/xJ qlECGDQ9en15zjN+XFgIrulmNDhn4jPWhZHbS/R7kU2JlijBod4EGDShQohNNCL/kpDJsR WIT0ZkxV40VBRJqzastutiJRkHMHkxtTNfr4BdG2iUeBaRGlkL2j2syOl9/gTk5U7W2fXj 385nYvWEcvPPz7+ni0lRNWqg6/2fRHjxzAVXpr9/l+BWi+bofwRlrltbDgrozA3A1dKVcJ 6zarlcNhYE4sJfy4L7qhHpeu7qzuriVRwMijO6fS1wgYQjezQp0QBsYDdCWkJQ== 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 6677425AB3; Fri, 17 Jun 2022 19:37:07 +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 25HJb7om012931; Fri, 17 Jun 2022 19:37:07 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25HJb7T3012930; Fri, 17 Jun 2022 19:37:07 GMT (envelope-from git) Date: Fri, 17 Jun 2022 19:37:07 GMT Message-Id: <202206171937.25HJb7T3012930@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dmitry Chagin Subject: git: 41ff17fb531b - stable/13 - linux(4): Factor out the FUTEX_CMP_REQUEUE op into linux_futex_requeue(). 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: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dchagin X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 41ff17fb531bea610d97b158b4af228100162e02 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655494628; 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=CyrDsSD4tw2p6/UhMCizve2mEbvLdSpNOnsGktE7mbc=; b=JqQT0CXJrC8+czWNJ0PWVRE2Hx3P9pKxECtRs0FHBc6tpEECJ8H31avTsmNZxeFGnN8vY9 /WKvz2VEGIzQ3pvcYwc/foEDZEhlwXP+U6m6UWEruBPj0Rb+VtQJx570G0WjHXCodVO8Fi TDzdeKDoZQCQ/mpHeCRgwhdluMcoC9t/K+xe4UnRCkryXJJjrfQ1cDHOtMv407HQjqTIe0 nxYp3kZCQLe2pPOO2kbT+0ohwNbmlPdkQTOXVg8piMJKXSEU9jrD/qdXwKN3Kr/H+Vph6j pHfRmncLhKLq6FPjJglHB1C4mzGQz8RFSZumEYNDa5j37xPMyi0esBbB8LzS4Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1655494628; a=rsa-sha256; cv=none; b=jkwqwcaGq4XkNbazy8/ueqAlHdEB1VHztWuPEU2PJkxt81I2egOQ81gKimNUPa8vwqdm/a 1DvfPTT6zUJrcQP7mOGmK+gvNmXhSwuPwENKh1ldO4LuL2UTuSg0t7l9cp8FNRQn64vCnm nvJmQc6zxh1Wq8CCWc1N9XNO46i7XOJ5zg/PMQQ4oiug7B/7kv9k7L/c93KLbpnZMI8c0W UOB1JKcytNVnmkqdMuFzUmYfPHS55x/jeBtZTLJgldaplDjnJfdiwK7+Rqzv14IGaG1Nqn 2wVoeK3tz29iuz132SqRYFvqOxZGDVnlWmMkj8V/Q5W9wHXr1GQl4UQF7LvsrA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=41ff17fb531bea610d97b158b4af228100162e02 commit 41ff17fb531bea610d97b158b4af228100162e02 Author: Dmitry Chagin AuthorDate: 2021-07-20 11:38:27 +0000 Commit: Dmitry Chagin CommitDate: 2022-06-17 19:33:11 +0000 linux(4): Factor out the FUTEX_CMP_REQUEUE op into linux_futex_requeue(). MFC after: 2 weeks (cherry picked from commit bb62a91944fa7985ebea29063721c633e28d0752) --- sys/compat/linux/linux_futex.c | 148 ++++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 68 deletions(-) diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index 04f767b8aed0..71ea8e320d73 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -240,6 +240,7 @@ struct linux_futex_args { static int linux_futex(struct thread *, struct linux_futex_args *); static int linux_futex_wait(struct thread *, struct linux_futex_args *); static int linux_futex_wake(struct thread *, struct linux_futex_args *); +static int linux_futex_requeue(struct thread *, struct linux_futex_args *); static void futex_put(struct futex *f, struct waiting_proc *wp) @@ -645,7 +646,7 @@ futex_atomic_op(struct thread *td, int encoded_op, uint32_t *uaddr) static int linux_futex(struct thread *td, struct linux_futex_args *args) { - int nrwake, nrrequeue, op_ret, ret; + int nrwake, op_ret, ret; struct linux_pemuldata *pem; struct futex *f, *f2; int error, save; @@ -709,73 +710,7 @@ linux_futex(struct thread *td, struct linux_futex_args *args) args->uaddr, args->val, args->val3, args->uaddr2, args->ts); - /* - * Linux allows this, we would not, it is an incorrect - * usage of declared ABI, so return EINVAL. - */ - if (args->uaddr == args->uaddr2) { - LIN_SDT_PROBE0(futex, linux_futex, - invalid_cmp_requeue_use); - return (EINVAL); - } - - nrrequeue = (int)(unsigned long)args->ts; - nrwake = args->val; - /* - * Sanity check to prevent signed integer overflow, - * see Linux CVE-2018-6927 - */ - if (nrwake < 0 || nrrequeue < 0) - return (EINVAL); - -retry1: - error = futex_get(args->uaddr, NULL, &f, - args->flags | FUTEX_DONTLOCK); - if (error) - return (error); - - /* - * To avoid deadlocks return EINVAL if second futex - * exists at this time. - * - * Glibc fall back to FUTEX_WAKE in case of any error - * returned by FUTEX_CMP_REQUEUE. - */ - error = futex_get(args->uaddr2, NULL, &f2, - args->flags | FUTEX_DONTEXISTS | FUTEX_DONTLOCK); - if (error) { - futex_put(f, NULL); - return (error); - } - futex_lock(f); - futex_lock(f2); - error = copyin_nofault(args->uaddr, &val, sizeof(val)); - if (error) { - futex_put(f2, NULL); - futex_put(f, NULL); - error = copyin(args->uaddr, &val, sizeof(val)); - if (error == 0) - goto retry1; - LIN_SDT_PROBE1(futex, linux_futex, copyin_error, - error); - LINUX_CTR1(sys_futex, "CMP_REQUEUE copyin failed %d", - error); - return (error); - } - if (val != args->val3) { - LIN_SDT_PROBE2(futex, linux_futex, - debug_cmp_requeue_value_neq, args->val, val); - LINUX_CTR2(sys_futex, "CMP_REQUEUE val 0x%x != uval 0x%x", - args->val, val); - futex_put(f2, NULL); - futex_put(f, NULL); - return (EAGAIN); - } - - td->td_retval[0] = futex_requeue(f, nrwake, f2, nrrequeue); - futex_put(f2, NULL); - futex_put(f, NULL); - break; + return (linux_futex_requeue(td, args)); case LINUX_FUTEX_WAKE_OP: LIN_SDT_PROBE5(futex, linux_futex, debug_wake_op, @@ -923,6 +858,83 @@ retry2: return (error); } +static int +linux_futex_requeue(struct thread *td, struct linux_futex_args *args) +{ + int nrwake, nrrequeue; + struct futex *f, *f2; + int error; + uint32_t val; + + /* + * Linux allows this, we would not, it is an incorrect + * usage of declared ABI, so return EINVAL. + */ + if (args->uaddr == args->uaddr2) { + LIN_SDT_PROBE0(futex, linux_futex, + invalid_cmp_requeue_use); + return (EINVAL); + } + + nrrequeue = (int)(unsigned long)args->ts; + nrwake = args->val; + /* + * Sanity check to prevent signed integer overflow, + * see Linux CVE-2018-6927 + */ + if (nrwake < 0 || nrrequeue < 0) + return (EINVAL); + +retry: + f = f2 = NULL; + error = futex_get(args->uaddr, NULL, &f, args->flags | FUTEX_DONTLOCK); + if (error != 0) + return (error); + + /* + * To avoid deadlocks return EINVAL if second futex + * exists at this time. + * + * Glibc fall back to FUTEX_WAKE in case of any error + * returned by FUTEX_CMP_REQUEUE. + */ + error = futex_get(args->uaddr2, NULL, &f2, + args->flags | FUTEX_DONTEXISTS | FUTEX_DONTLOCK); + if (error != 0) { + futex_put(f, NULL); + return (error); + } + futex_lock(f); + futex_lock(f2); + error = copyin_nofault(args->uaddr, &val, sizeof(val)); + if (error != 0) { + futex_put(f2, NULL); + futex_put(f, NULL); + error = copyin(args->uaddr, &val, sizeof(val)); + if (error == 0) + goto retry; + LIN_SDT_PROBE1(futex, linux_futex, copyin_error, + error); + LINUX_CTR1(sys_futex, "CMP_REQUEUE copyin failed %d", + error); + return (error); + } + if (val != args->val3) { + LIN_SDT_PROBE2(futex, linux_futex, + debug_cmp_requeue_value_neq, args->val, val); + LINUX_CTR2(sys_futex, "CMP_REQUEUE val 0x%x != uval 0x%x", + args->val, val); + futex_put(f2, NULL); + futex_put(f, NULL); + return (EAGAIN); + } + + td->td_retval[0] = futex_requeue(f, nrwake, f2, nrrequeue); + futex_put(f2, NULL); + futex_put(f, NULL); + return (0); +} + static int linux_futex_wake(struct thread *td, struct linux_futex_args *args) {