Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102136382
D30151.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D30151.diff
View Options
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -3741,7 +3741,11 @@
struct sockaddr *addr, struct mbuf *control, struct thread *td)
{
- return EOPNOTSUPP;
+ if (control != NULL)
+ m_freem(control);
+ if ((flags & PRUS_NOTREADY) == 0)
+ m_freem(m);
+ return (EOPNOTSUPP);
}
int
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -677,6 +677,8 @@
if (m->m_len < sizeof (struct ip) &&
(m = m_pullup(m, sizeof (struct ip))) == NULL) {
KMOD_IPSTAT_INC(ips_toosmall);
+ if (control != NULL)
+ m_freem(control);
m_freem(m);
return EINVAL;
}
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1077,13 +1077,18 @@
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("rip_send: inp == NULL"));
+ if (control != NULL) {
+ m_freem(control);
+ control = NULL;
+ }
+
/*
* Note: 'dst' reads below are unlocked.
*/
if (so->so_state & SS_ISCONNECTED) {
if (nam) {
- m_freem(m);
- return (EISCONN);
+ error = EISCONN;
+ goto release;
}
dst = inp->inp_faddr.s_addr; /* Unlocked read. */
} else {
@@ -1094,13 +1099,15 @@
error = EAFNOSUPPORT;
else if (nam->sa_len != sizeof(struct sockaddr_in))
error = EINVAL;
- if (error != 0) {
- m_freem(m);
- return (error);
- }
+ if (error != 0)
+ goto release;
dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr;
}
return (rip_output(m, so, dst));
+
+release:
+ m_freem(m);
+ return (error);
}
#endif /* INET */
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -993,21 +993,31 @@
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
if (control)
m_freem(control);
+
/*
* In case of PRUS_NOTREADY, tcp_usr_ready() is responsible
* for freeing memory.
*/
- if (m && (flags & PRUS_NOTREADY) == 0)
+ if ((flags & PRUS_NOTREADY) == 0)
m_freem(m);
error = ECONNRESET;
goto out;
}
+ if (control != NULL) {
+ /* TCP doesn't do control messages (rights, creds, etc) */
+ if (control->m_len) {
+ m_freem(control);
+ m_freem(m);
+ error = EINVAL;
+ goto out;
+ }
+ m_freem(control); /* empty control, just free it */
+ control = NULL;
+ }
tp = intotcpcb(inp);
if (flags & PRUS_OOB) {
if ((error = tcp_pru_options_support(tp, PRUS_OOB)) != 0) {
- if (control)
- m_freem(control);
- if (m && (flags & PRUS_NOTREADY) == 0)
+ if ((flags & PRUS_NOTREADY) == 0)
m_freem(m);
goto out;
}
@@ -1019,33 +1029,28 @@
case AF_INET:
sinp = (struct sockaddr_in *)nam;
if (sinp->sin_len != sizeof(struct sockaddr_in)) {
- if (m)
- m_freem(m);
+ m_freem(m);
error = EINVAL;
goto out;
}
if ((inp->inp_vflag & INP_IPV6) != 0) {
- if (m)
- m_freem(m);
+ m_freem(m);
error = EAFNOSUPPORT;
goto out;
}
if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
- if (m)
- m_freem(m);
+ m_freem(m);
error = EAFNOSUPPORT;
goto out;
}
if (ntohl(sinp->sin_addr.s_addr) == INADDR_BROADCAST) {
- if (m)
- m_freem(m);
+ m_freem(m);
error = EACCES;
goto out;
}
if ((error = prison_remote_ip4(td->td_ucred,
&sinp->sin_addr))) {
- if (m)
- m_freem(m);
+ m_freem(m);
goto out;
}
#ifdef INET6
@@ -1060,20 +1065,17 @@
sin6 = (struct sockaddr_in6 *)nam;
if (sin6->sin6_len != sizeof(*sin6)) {
- if (m)
- m_freem(m);
+ m_freem(m);
error = EINVAL;
goto out;
}
if ((inp->inp_vflag & INP_IPV6PROTO) == 0) {
- if (m != NULL)
- m_freem(m);
+ m_freem(m);
error = EAFNOSUPPORT;
goto out;
}
if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
- if (m)
- m_freem(m);
+ m_freem(m);
error = EAFNOSUPPORT;
goto out;
}
@@ -1081,14 +1083,12 @@
#ifdef INET
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
error = EINVAL;
- if (m)
- m_freem(m);
+ m_freem(m);
goto out;
}
if ((inp->inp_vflag & INP_IPV4) == 0) {
error = EAFNOSUPPORT;
- if (m)
- m_freem(m);
+ m_freem(m);
goto out;
}
restoreflags = true;
@@ -1098,27 +1098,23 @@
if (IN_MULTICAST(
ntohl(sinp->sin_addr.s_addr))) {
error = EAFNOSUPPORT;
- if (m)
- m_freem(m);
+ m_freem(m);
goto out;
}
if ((error = prison_remote_ip4(td->td_ucred,
&sinp->sin_addr))) {
- if (m)
- m_freem(m);
+ m_freem(m);
goto out;
}
isipv6 = 0;
#else /* !INET */
error = EAFNOSUPPORT;
- if (m)
- m_freem(m);
+ m_freem(m);
goto out;
#endif /* INET */
} else {
if ((inp->inp_vflag & INP_IPV6) == 0) {
- if (m)
- m_freem(m);
+ m_freem(m);
error = EAFNOSUPPORT;
goto out;
}
@@ -1127,8 +1123,7 @@
inp->inp_inc.inc_flags |= INC_ISIPV6;
if ((error = prison_remote_ip6(td->td_ucred,
&sin6->sin6_addr))) {
- if (m)
- m_freem(m);
+ m_freem(m);
goto out;
}
isipv6 = 1;
@@ -1137,23 +1132,11 @@
}
#endif /* INET6 */
default:
- if (m)
- m_freem(m);
+ m_freem(m);
error = EAFNOSUPPORT;
goto out;
}
}
- if (control) {
- /* TCP doesn't do control messages (rights, creds, etc) */
- if (control->m_len) {
- m_freem(control);
- if (m)
- m_freem(m);
- error = EINVAL;
- goto out;
- }
- m_freem(control); /* empty control, just free it */
- }
if (!(flags & PRUS_OOB)) {
sbappendstream(&so->so_snd, m, flags);
if (nam && tp->t_state < TCPS_SYN_SENT) {
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1273,6 +1273,7 @@
break;
}
m_freem(control);
+ control = NULL;
}
if (error)
goto release;
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -867,7 +867,7 @@
struct inpcb *inp;
struct sockaddr_in6 tmp;
struct sockaddr_in6 *dst;
- int ret;
+ int error;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("rip6_send: inp == NULL"));
@@ -876,8 +876,8 @@
/* Unlocked read. */
if (so->so_state & SS_ISCONNECTED) {
if (nam) {
- m_freem(m);
- return (EISCONN);
+ error = EISCONN;
+ goto release;
}
/* XXX */
bzero(&tmp, sizeof(tmp));
@@ -889,18 +889,15 @@
INP_RUNLOCK(inp);
dst = &tmp;
} else {
- if (nam == NULL) {
- m_freem(m);
- return (ENOTCONN);
- }
- if (nam->sa_family != AF_INET6) {
- m_freem(m);
- return (EAFNOSUPPORT);
- }
- if (nam->sa_len != sizeof(struct sockaddr_in6)) {
- m_freem(m);
- return (EINVAL);
- }
+ error = 0;
+ if (nam == NULL)
+ error = ENOTCONN;
+ else if (nam->sa_family != AF_INET6)
+ error = EAFNOSUPPORT;
+ else if (nam->sa_len != sizeof(struct sockaddr_in6))
+ error = EINVAL;
+ if (error != 0)
+ goto release;
tmp = *(struct sockaddr_in6 *)nam;
dst = &tmp;
@@ -914,12 +911,17 @@
"unspec. Assume AF_INET6\n");
dst->sin6_family = AF_INET6;
} else if (dst->sin6_family != AF_INET6) {
- m_freem(m);
- return(EAFNOSUPPORT);
+ error = EAFNOSUPPORT;
+ goto release;
}
}
- ret = rip6_output(m, so, dst, control);
- return (ret);
+ return (rip6_output(m, so, dst, control));
+
+release:
+ if (control != NULL)
+ m_freem(control);
+ m_freem(m);
+ return (error);
}
struct pr_usrreqs rip6_usrreqs = {
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -713,6 +713,11 @@
#ifdef INET
case AF_INET:
if (addr->sa_len != sizeof(struct sockaddr_in)) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
@@ -721,12 +726,22 @@
#ifdef INET6
case AF_INET6:
if (addr->sa_len != sizeof(struct sockaddr_in6)) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
break;
#endif
default:
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
@@ -738,10 +753,20 @@
* v4 addr or v4-mapped addr
*/
if (addr->sa_family == AF_INET) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
diff --git a/sys/netinet6/send.c b/sys/netinet6/send.c
--- a/sys/netinet6/send.c
+++ b/sys/netinet6/send.c
@@ -250,8 +250,11 @@
m = NULL;
err:
+ if (control != NULL)
+ m_freem(control);
if (m != NULL)
m_freem(m);
+
return (error);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 9, 1:49 AM (21 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14547719
Default Alt Text
D30151.diff (9 KB)
Attached To
Mode
D30151: Fix mbuf leaks in various pru_send implementations
Attached
Detach File
Event Timeline
Log In to Comment