From de5b078e4da89d76086ab50bca6d0e232ed400d3 Mon Sep 17 00:00:00 2001 From: mvs Date: Thu, 18 Feb 2021 11:40:19 +0000 Subject: [PATCH] Release mbuf(9) chain with a simple m_freem(9) loop in sorflush(). Passing local copy of socket to sbrelease() is too complicated to just free receive buffer. We don't allocate large object on the stack. Also we don't pass unlocked socket to soassertlocked() within sbdrop(). This was not triggered because we lock the whole layer with one lock. Also sorflush() is now private to kern/uipc_socket.c, so it's definition was made to be in accordance. ok claudio@ mpi@ --- sys/kern/uipc_socket.c | 13 +++++++------ sys/sys/socketvar.h | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index b629ba7c28f..71f2a49ca17 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.254 2021/01/17 05:23:34 visa Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.255 2021/02/18 11:40:19 mvs Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -66,6 +66,7 @@ void sotask(void *); void soreaper(void *); void soput(void *); int somove(struct socket *, int); +void sorflush(struct socket *); void filt_sordetach(struct knote *kn); int filt_soread(struct knote *kn, long hint); @@ -1116,8 +1117,8 @@ void sorflush(struct socket *so) { struct sockbuf *sb = &so->so_rcv; + struct mbuf *m; const struct protosw *pr = so->so_proto; - struct socket aso; int error; sb->sb_flags |= SB_NOINTR; @@ -1126,14 +1127,14 @@ sorflush(struct socket *so) KASSERT(error == 0); socantrcvmore(so); sbunlock(so, sb); - aso.so_proto = pr; - aso.so_rcv = *sb; + m = sb->sb_mb; memset(&sb->sb_startzero, 0, (caddr_t)&sb->sb_endzero - (caddr_t)&sb->sb_startzero); sb->sb_timeo_nsecs = INFSLP; if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) - (*pr->pr_domain->dom_dispose)(aso.so_rcv.sb_mb); - sbrelease(&aso, &aso.so_rcv); + (*pr->pr_domain->dom_dispose)(m); + while (m != NULL) + m = m_freem(m); } #ifdef SOCKET_SPLICE diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index c5c1b448926..9f6f2488e2a 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: socketvar.h,v 1.92 2021/01/17 05:23:34 visa Exp $ */ +/* $OpenBSD: socketvar.h,v 1.93 2021/02/18 11:40:20 mvs Exp $ */ /* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */ /*- @@ -325,7 +325,6 @@ int soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp, socklen_t controllen); int soreserve(struct socket *so, u_long sndcc, u_long rcvcc); -void sorflush(struct socket *so); int sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags); int sosetopt(struct socket *so, int level, int optname, struct mbuf *m); -- 2.20.1