From c3d495a1d6f1d1d2052ade59291d9442ba78e029 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 20 Oct 2010 10:41:38 -0700 Subject: [PATCH] network - Fix socket & mbuf leak * When I retooled soabort*() and removed the wrapper I accidently lost the sofree() mechanic in the wrapper. * Replace the mechanic with a messaged version. Reported-by: Peter Avalos --- sys/kern/uipc_msg.c | 10 +++++++--- sys/net/netisr.c | 10 ++++++++++ sys/net/netisr.h | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/sys/kern/uipc_msg.c b/sys/kern/uipc_msg.c index 9a10533794..b2670ce319 100644 --- a/sys/kern/uipc_msg.c +++ b/sys/kern/uipc_msg.c @@ -51,7 +51,8 @@ #include /* - * Abort a socket and free it. Called from soabort() only. + * Abort a socket and free it. Called from soabort() only. soabort() + * got a ref on the socket which we must free on reply. */ void so_pru_abort(struct socket *so) @@ -61,11 +62,13 @@ so_pru_abort(struct socket *so) netmsg_init(&msg.base, so, &curthread->td_msgport, 0, so->so_proto->pr_usrreqs->pru_abort); (void)lwkt_domsg(so->so_port, &msg.base.lmsg, 0); + sofree(msg.base.nm_so); } /* * Abort a socket and free it, asynchronously. Called from - * soaborta() only. + * soaborta() only. soaborta() got a ref on the socket which we must + * free on reply. */ void so_pru_aborta(struct socket *so) @@ -73,7 +76,7 @@ so_pru_aborta(struct socket *so) struct netmsg_pru_abort *msg; msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_WAITOK | M_ZERO); - netmsg_init(&msg->base, so, &netisr_afree_rport, + netmsg_init(&msg->base, so, &netisr_afree_free_so_rport, 0, so->so_proto->pr_usrreqs->pru_abort); lwkt_sendmsg(so->so_port, &msg->base.lmsg); } @@ -93,6 +96,7 @@ so_pru_abort_oncpu(struct socket *so) msg.base.lmsg.ms_flags |= MSGF_SYNC; func((netmsg_t)&msg); KKASSERT(msg.base.lmsg.ms_flags & MSGF_DONE); + sofree(msg.base.nm_so); } /* diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 911aba6366..73561ffe01 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -79,6 +79,7 @@ static TAILQ_HEAD(,netmsg_rollup) netrulist; /* Per-CPU thread to handle any protocol. */ static struct thread netisr_cpu[MAXCPU]; lwkt_port netisr_afree_rport; +lwkt_port netisr_afree_free_so_rport; lwkt_port netisr_adone_rport; lwkt_port netisr_apanic_rport; lwkt_port netisr_sync_port; @@ -97,6 +98,13 @@ netisr_autofree_reply(lwkt_port_t port, lwkt_msg_t msg) kfree(msg, M_LWKTMSG); } +static void +netisr_autofree_free_so_reply(lwkt_port_t port, lwkt_msg_t msg) +{ + sofree(((netmsg_t)msg)->base.nm_so); + kfree(msg, M_LWKTMSG); +} + /* * We need a custom putport function to handle the case where the * message target is the current thread's message port. This case @@ -172,6 +180,8 @@ netisr_init(void) * the message is replied to. */ lwkt_initport_replyonly(&netisr_afree_rport, netisr_autofree_reply); + lwkt_initport_replyonly(&netisr_afree_free_so_rport, + netisr_autofree_free_so_reply); lwkt_initport_replyonly_null(&netisr_adone_rport); lwkt_initport_panic(&netisr_apanic_rport); diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 4d897d9f9e..71eb70bf54 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -165,6 +165,7 @@ struct netisr { extern lwkt_port netisr_adone_rport; extern lwkt_port netisr_afree_rport; +extern lwkt_port netisr_afree_free_so_rport; extern lwkt_port netisr_apanic_rport; extern lwkt_port netisr_sync_port; -- 2.11.4.GIT