Date: Tue, 15 Apr 2025 00:57:30 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 992b18a9ec9f - main - so_splice: Synchronize so_unsplice() with so_splice() Message-ID: <202504150057.53F0vUis046025@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=992b18a9ec9f21cdf15b70b2f510fa2a69844385 commit 992b18a9ec9f21cdf15b70b2f510fa2a69844385 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2025-04-15 00:55:00 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2025-04-15 00:55:00 +0000 so_splice: Synchronize so_unsplice() with so_splice() so_unsplice() assumed that if SB_SPLICED is set in the receive buffer of the first socket, then the splice is fully initialized. However, that's not true, and it's possible for so_unsplice() to race ahead of so_splice(). Modify so_unsplice() to simply bail if the splice state is embryonic. Reported by: syzkaller Reviewed by: gallatin Fixes: a1da7dc1cdad ("socket: Implement SO_SPLICE") MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D49814 --- sys/kern/uipc_socket.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index ac00696236a5..291a832189e5 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1742,6 +1742,8 @@ so_splice(struct socket *so, struct socket *so2, struct splice *splice) /* * Transfer any data already present in the socket buffer. */ + KASSERT(sp->state == SPLICE_INIT, + ("so_splice: splice %p state %d", sp, sp->state)); sp->state = SPLICE_QUEUED; so_splice_xfer(sp); return (0); @@ -1770,8 +1772,19 @@ so_unsplice(struct socket *so, bool timeout) SOCK_UNLOCK(so); return (ENOTCONN); } - so->so_rcv.sb_flags &= ~SB_SPLICED; sp = so->so_splice; + mtx_lock(&sp->mtx); + if (sp->state == SPLICE_INIT) { + /* + * A splice is in the middle of being set up. + */ + mtx_unlock(&sp->mtx); + SOCK_RECVBUF_UNLOCK(so); + SOCK_UNLOCK(so); + return (ENOTCONN); + } + mtx_unlock(&sp->mtx); + so->so_rcv.sb_flags &= ~SB_SPLICED; so->so_splice = NULL; SOCK_RECVBUF_UNLOCK(so); SOCK_UNLOCK(so);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202504150057.53F0vUis046025>