From nobody Thu Jun 16 14:36:26 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 56EC885DA45; Thu, 16 Jun 2022 14:36:27 +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 4LP4Vf6tr4z3tD6; Thu, 16 Jun 2022 14:36:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655390187; 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=DxHjJA/A9iyY6pJokwzgjG5wvuVCxAhic2qqlZ+fdVY=; b=UgkEmecWbF4tVDj6nYAQY/S4SmfkWERbTO24NrRiICtseEHmNr8/fE671dOL/KIQsaRzU4 j0gKzysCS0zX/gyjSe/uCNQ79ow5t5Vxkt1wDaPE+ND7Lz/VfChX1nK2ZLT+vECbdVPd3r 0ciUGkSu9wzQb5CxyeZUo21JWttqwp6eMIn6maAF0SG6hAvpLexj719xC4UnIMj/yFICqb aGMwrBJUY40NXcJLDl7f8ExI204i+0g/kAwLYcSxRWqQ9YIsyq4aw6OlMfoR4Y+oHwHHc9 wvQ6qXqCMhSbLvPeCJh5VczbzDT9QLtp4gxWC3TWhHCWX63pNYbfowKfZVDL6Q== 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 83415526E; Thu, 16 Jun 2022 14:36:26 +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 25GEaQqt056720; Thu, 16 Jun 2022 14:36:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25GEaQvF056719; Thu, 16 Jun 2022 14:36:26 GMT (envelope-from git) Date: Thu, 16 Jun 2022 14:36:26 GMT Message-Id: <202206161436.25GEaQvF056719@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: f6379f7fdec0 - main - socket: Fix a race between kevent(2) and listen(2) 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: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f6379f7fdec030e2ede75454cb61d25517606eaa Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655390187; 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=DxHjJA/A9iyY6pJokwzgjG5wvuVCxAhic2qqlZ+fdVY=; b=kBAdvmxFJErVh38oFJkhkxCJx7xpvcW/VlFmEJwB+SGJS4/hkr718jN5Lbkks8J2Fmmz3m cNKCd0c3wmo0jMFlGVXjx/aswbLhRliW9Cwe7mCwSXHuAxjADolrMM3zbhFHMBlLJ/rvQt pVw08/hAg7LWEIl+iYc+6flXO/oCpKVsjFnbBjMAIwZAIgxN5NgF3/A7bnfbA2bXQUP1By Gu/TioPM28tNBgS670nkiRfst8MtskWB7IJERO23pJpCdgjIeL0cLIUGOPKghi4arSA+Tt 7khV5x+4n2DAH+FilgQrvw/Q4PKJPFZyGRI8DrBOeKddbeXZKtoXxRPE2FiSXw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1655390187; a=rsa-sha256; cv=none; b=YnvTGXiW0kn0sD50rJ1wElm8PibKh1++9K2oog0Nt87Dw4JTk5K6gnCQYZl0nsM7Zv9Ksr JevgenRqEgbMgInnYHHBeHB8gwjRgNuAPJSQRnfAtusdWjWy0W24eWbnTGNDlxCFe7xsbK LfbX2ZPz/cIIVeV0na7bWFIHJ4N1Zw9iJ2geDn1vR+cXr0gLC/hhjx/pRVFucRQLkcjCIB gatdYTJCo7olV7gJdZy2ZEeAmNNEHNNRRQm+h0QmB+UPeXAqqq20VavVf9PMAIi0a11KKM XcG0Q1x/rC5raQ7maammysoQvc84UlPz+nvEHqT9Iq8tv43Jfc6/Vvv7JlduaQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=f6379f7fdec030e2ede75454cb61d25517606eaa commit f6379f7fdec030e2ede75454cb61d25517606eaa Author: Mark Johnston AuthorDate: 2022-06-16 14:10:45 +0000 Commit: Mark Johnston CommitDate: 2022-06-16 14:20:04 +0000 socket: Fix a race between kevent(2) and listen(2) When locking the knote list for a socket, we check whether the socket is a listening socket in order to select the appropriate mutex; a listening socket uses the socket lock, while data sockets use socket buffer mutexes. If SOLISTENING(so) is false and the knote lock routine locks a socket buffer, then it must re-check whether the socket is a listening socket since solisten_proto() could have changed the socket's identity while we were blocked on the socket buffer lock. Reported by: syzkaller Reviewed by: glebius MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D35492 --- sys/kern/uipc_socket.c | 36 ++++++++++++++++++++++++------------ sys/sys/socketvar.h | 5 +++++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 2a01f656d258..a2241464e35b 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -4273,10 +4273,16 @@ so_rdknl_lock(void *arg) { struct socket *so = arg; - if (SOLISTENING(so)) - SOCK_LOCK(so); - else +retry: + if (SOLISTENING(so)) { + SOLISTEN_LOCK(so); + } else { SOCK_RECVBUF_LOCK(so); + if (__predict_false(SOLISTENING(so))) { + SOCK_RECVBUF_UNLOCK(so); + goto retry; + } + } } static void @@ -4285,7 +4291,7 @@ so_rdknl_unlock(void *arg) struct socket *so = arg; if (SOLISTENING(so)) - SOCK_UNLOCK(so); + SOLISTEN_UNLOCK(so); else SOCK_RECVBUF_UNLOCK(so); } @@ -4297,12 +4303,12 @@ so_rdknl_assert_lock(void *arg, int what) if (what == LA_LOCKED) { if (SOLISTENING(so)) - SOCK_LOCK_ASSERT(so); + SOLISTEN_LOCK_ASSERT(so); else SOCK_RECVBUF_LOCK_ASSERT(so); } else { if (SOLISTENING(so)) - SOCK_UNLOCK_ASSERT(so); + SOLISTEN_UNLOCK_ASSERT(so); else SOCK_RECVBUF_UNLOCK_ASSERT(so); } @@ -4313,10 +4319,16 @@ so_wrknl_lock(void *arg) { struct socket *so = arg; - if (SOLISTENING(so)) - SOCK_LOCK(so); - else +retry: + if (SOLISTENING(so)) { + SOLISTEN_LOCK(so); + } else { SOCK_SENDBUF_LOCK(so); + if (__predict_false(SOLISTENING(so))) { + SOCK_SENDBUF_UNLOCK(so); + goto retry; + } + } } static void @@ -4325,7 +4337,7 @@ so_wrknl_unlock(void *arg) struct socket *so = arg; if (SOLISTENING(so)) - SOCK_UNLOCK(so); + SOLISTEN_UNLOCK(so); else SOCK_SENDBUF_UNLOCK(so); } @@ -4337,12 +4349,12 @@ so_wrknl_assert_lock(void *arg, int what) if (what == LA_LOCKED) { if (SOLISTENING(so)) - SOCK_LOCK_ASSERT(so); + SOLISTEN_LOCK_ASSERT(so); else SOCK_SENDBUF_LOCK_ASSERT(so); } else { if (SOLISTENING(so)) - SOCK_UNLOCK_ASSERT(so); + SOLISTEN_UNLOCK_ASSERT(so); else SOCK_SENDBUF_UNLOCK_ASSERT(so); } diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 249e0800f915..85aa7cbfea0f 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -254,6 +254,11 @@ struct socket { KASSERT(SOLISTENING(sol), \ ("%s: %p not listening", __func__, (sol))); \ } while (0) +#define SOLISTEN_UNLOCK_ASSERT(sol) do { \ + mtx_assert(&(sol)->so_lock, MA_NOTOWNED); \ + KASSERT(SOLISTENING(sol), \ + ("%s: %p not listening", __func__, (sol))); \ +} while (0) /* * Socket buffer locks. These are strongly preferred over SOCKBUF_LOCK(sb)