From nobody Tue Sep 12 23:39:00 2023 X-Original-To: dev-commits-src-main@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 4Rlg5c6yS2z4t6VR; Tue, 12 Sep 2023 23:39:00 +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 4Rlg5c6XkBz3Cq6; Tue, 12 Sep 2023 23:39:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1694561940; 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=1Xj+HWE8iaEsfz0/eduvECYvF/p86yMosxzH7rsgLsw=; b=OwnspFqrDp3FUc9sSXiRSm6j1ynDzmEqGjjjANLf3Xdd7/lqdl/1abUpS8XgPcjx8g4CW7 wVcJgwAOtqoMAR8qle4lFwNHquLkP6ZgSNMwKlxECIlPxwXxS3EXhogpY3TfHrMFH2p3a+ LsLFf9/0V/CaNu8n17lM+vGrguZOX6I/IxoAKrrQd57yS0p/2K8gCGynh+5R/FVjvguzR+ uh1D3i42UQK6OvTkQljebR0ipH7Ds7k2NjKyeecTpG1uBfSbp5yVQi6eA+CDloCDCJVDfl K4DI+bv9Di4pG9eOYnc7SgI+B6bHPpBzKKb+B14F7Gfe/OQzW++xehwQ1yVNWw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1694561940; a=rsa-sha256; cv=none; b=rziOIJcJ1hpHIVuZfCV+/GgOZMnUr/mJ0/TOeTnU2qj173R5l3camb3k+L/Q8dofTgD1bS C+PZMi8Cwz1k0Vi+1jGnYfscPiOpB1EGcqbSMyDACkyamL5wn2lHbFmCOj6NnfjFhV3Fg7 wCifoIhUOB94Q0hfW9gYqkJY0dc80KPF6vfOJFGKmyf1oELmTiGeppiRSqtwyF9eXGSvJM hOXumbhf9j7KCru1bfM+Z6dD0rR8eUwtTz+80cwDS0yufKcAE1z6LGADKu0UezpUc9SJs2 a5L2gvApq1tm0HZqAG7t1SM14pn9LvhYDF9JpHIl6ItozcaSXFAjth9lw/le4Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1694561940; 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=1Xj+HWE8iaEsfz0/eduvECYvF/p86yMosxzH7rsgLsw=; b=iZCJZFSuaXBLSqIY/dpnQnCadCuEwiu4SKbSuqfcpjrPYZFQQosjggVEkB9v/xSTuLHnIP hMBsin6svgRfXV7l8Kgs7Iw93kymns5n/ytzniUpjpq9C+syXvUTJSvlKrkDx11A6BCUqz TZBwNexWdGKFKd3uLLKIcFA6p6TJ9MlhRdJOlP7V/4lQ32kI4jwGNi8cZ0d/h2CtMICeNZ DPWKNiQmgUeE+5uK6QN/qmmHZh8xiPZmpCSddOkYCwZVfw9BdV4c7r+8KMxW1jIZU81D0j o2JspHJ6ZyeGIkv8vw8WqJZxcFHrrmAjWdOpE0GDcKswNHADjD8ezPn/N3FlSA== 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 4Rlg5c5GN3zrYY; Tue, 12 Sep 2023 23:39:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 38CNd0Gk054411; Tue, 12 Sep 2023 23:39:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 38CNd0Au054408; Tue, 12 Sep 2023 23:39:00 GMT (envelope-from git) Date: Tue, 12 Sep 2023 23:39:00 GMT Message-Id: <202309122339.38CNd0Au054408@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Michael Tuexen Subject: git: 81c5f0fac91d - main - sctp: improve shutting down the read side of a socket List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: tuexen X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 81c5f0fac91dfae64205a6c4f9b2a469d1187372 Auto-Submitted: auto-generated The branch main has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=81c5f0fac91dfae64205a6c4f9b2a469d1187372 commit 81c5f0fac91dfae64205a6c4f9b2a469d1187372 Author: Michael Tuexen AuthorDate: 2023-09-12 23:33:54 +0000 Commit: Michael Tuexen CommitDate: 2023-09-12 23:36:14 +0000 sctp: improve shutting down the read side of a socket When shutdown(..., SHUT_RD) or shutdown(..., SHUT_RDWR) is called, really clean up the read queue and issue an ungraceful shutdown if user messages are affected. Reported by: syzbot+d4e1d30d578891245f59@syzkaller.appspotmail.com MFC after: 3 days --- sys/netinet/sctp_usrreq.c | 90 ++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 52b4faf48574..02bb87578528 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -777,52 +777,76 @@ sctp_disconnect(struct socket *so) int sctp_flush(struct socket *so, int how) { - /* - * We will just clear out the values and let subsequent close clear - * out the data, if any. Note if the user did a shutdown(SHUT_RD) - * they will not be able to read the data, the socket will block - * that from happening. - */ + struct epoch_tracker et; + struct sctp_tcb *stcb; + struct sctp_queued_to_read *control, *ncontrol; struct sctp_inpcb *inp; + struct mbuf *m, *op_err; + bool need_to_abort = false; + /* + * For 1-to-1 style sockets, flush the read queue and trigger an + * ungraceful shutdown of the association, if and only if user + * messages are lost. Loosing notifications does not need to be + * signalled to the peer. + */ + if (how == PRU_FLUSH_WR) { + /* This function is only relevant for the read directions. */ + return (0); + } inp = (struct sctp_inpcb *)so->so_pcb; if (inp == NULL) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); return (EINVAL); } - SCTP_INP_RLOCK(inp); - /* For the 1 to many model this does nothing */ + SCTP_INP_WLOCK(inp); if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { - SCTP_INP_RUNLOCK(inp); + /* For 1-to-many style sockets this function does nothing. */ + SCTP_INP_WUNLOCK(inp); return (0); } - SCTP_INP_RUNLOCK(inp); - if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) { - /* - * First make sure the sb will be happy, we don't use these - * except maybe the count - */ - SCTP_INP_WLOCK(inp); - SCTP_INP_READ_LOCK(inp); - inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ; - SCTP_INP_READ_UNLOCK(inp); + stcb = LIST_FIRST(&inp->sctp_asoc_list); + if (stcb == NULL) { SCTP_INP_WUNLOCK(inp); - SOCK_LOCK(so); - KASSERT(!SOLISTENING(so), - ("sctp_flush: called on listening socket %p", so)); - SCTP_SB_CLEAR(so->so_rcv); - SOCK_UNLOCK(so); + return (ENOTCONN); } - if ((how == PRU_FLUSH_WR) || (how == PRU_FLUSH_RDWR)) { - /* - * First make sure the sb will be happy, we don't use these - * except maybe the count - */ - SOCK_LOCK(so); - KASSERT(!SOLISTENING(so), - ("sctp_flush: called on listening socket %p", so)); - SOCK_UNLOCK(so); + SCTP_TCB_LOCK(stcb); + SCTP_INP_READ_LOCK(inp); + inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ; + SOCK_LOCK(so); + TAILQ_FOREACH_SAFE(control, &inp->read_queue, next, ncontrol) { + if ((control->spec_flags & M_NOTIFICATION) == 0) { + need_to_abort = true; + } + TAILQ_REMOVE(&inp->read_queue, control, next); + control->on_read_q = 0; + for (m = control->data; m; m = SCTP_BUF_NEXT(m)) { + sctp_sbfree(control, control->stcb, &so->so_rcv, m); + } + if (control->on_strm_q == 0) { + sctp_free_remote_addr(control->whoFrom); + if (control->data) { + sctp_m_freem(control->data); + control->data = NULL; + } + sctp_free_a_readq(stcb, control); + } else { + stcb->asoc.size_on_all_streams += control->length; + } } + SOCK_UNLOCK(so); + SCTP_INP_READ_UNLOCK(inp); + if (need_to_abort) { + inp->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6; + SCTP_INP_WUNLOCK(inp); + op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); + NET_EPOCH_ENTER(et); + sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_LOCKED); + NET_EPOCH_EXIT(et); + return (ECONNABORTED); + } + SCTP_TCB_UNLOCK(stcb); + SCTP_INP_WUNLOCK(inp); return (0); }