Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115485365
D29519.id86631.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D29519.id86631.diff
View Options
Index: sys/dev/hyperv/hvsock/hv_sock.c
===================================================================
--- sys/dev/hyperv/hvsock/hv_sock.c
+++ sys/dev/hyperv/hvsock/hv_sock.c
@@ -300,6 +300,7 @@
{
memset(addr, 0, sizeof(*addr));
addr->sa_family = AF_HYPERV;
+ addr->sa_len = sizeof(*addr);
addr->hvs_port = port;
}
@@ -430,6 +431,12 @@
__func__, sa->sa_family);
return (EAFNOSUPPORT);
}
+ if (sa->sa_len != sizeof(*sa)) {
+ HVSOCK_DBG(HVSOCK_DBG_ERR,
+ "%s: Not supported, sa_len is %u\n",
+ __func__, sa->sa_len);
+ return (EINVAL);
+ }
HVSOCK_DBG(HVSOCK_DBG_VERBOSE,
"%s: binding port = 0x%x\n", __func__, sa->hvs_port);
@@ -521,6 +528,8 @@
return (EINVAL);
if (raddr->sa_family != AF_HYPERV)
return (EAFNOSUPPORT);
+ if (raddr->sa_len != sizeof(*raddr))
+ return (EINVAL);
mtx_lock(&hvs_trans_socks_mtx);
if (so->so_state &
Index: sys/netgraph/ng_socket.c
===================================================================
--- sys/netgraph/ng_socket.c
+++ sys/netgraph/ng_socket.c
@@ -240,6 +240,11 @@
goto release;
}
+ if (sap->sg_len > NG_NODESIZ + 2) {
+ error = EINVAL;
+ goto release;
+ }
+
/*
* Allocate an expendable buffer for the path, chop off
* the sockaddr header, and make sure it's NUL terminated.
@@ -422,10 +427,15 @@
goto release;
}
- if (sap == NULL)
+ if (sap == NULL) {
len = 0; /* Make compiler happy. */
- else
+ } else {
+ if (sap->sg_len > NG_NODESIZ + 2) {
+ error = EINVAL;
+ goto release;
+ }
len = sap->sg_len - 2;
+ }
/*
* If the user used any of these ways to not specify an address
Index: sys/netinet/in_pcb.c
===================================================================
--- sys/netinet/in_pcb.c
+++ sys/netinet/in_pcb.c
@@ -654,6 +654,10 @@
{
int anonport, error;
+ KASSERT(nam == NULL || nam->sa_family == AF_INET,
+ ("%s: invalid address family for %p", __func__, nam));
+ KASSERT(nam == NULL || nam->sa_len == sizeof(struct sockaddr_in),
+ ("%s: invalid address length for %p", __func__, nam));
INP_WLOCK_ASSERT(inp);
INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
@@ -940,16 +944,11 @@
return (error);
} else {
sin = (struct sockaddr_in *)nam;
- if (nam->sa_len != sizeof (*sin))
- return (EINVAL);
-#ifdef notdef
- /*
- * We should check the family, but old programs
- * incorrectly fail to initialize it.
- */
- if (sin->sin_family != AF_INET)
- return (EAFNOSUPPORT);
-#endif
+ KASSERT(sin->sin_family == AF_INET,
+ ("%s: invalid family for address %p", __func__, sin));
+ KASSERT(sin->sin_len == sizeof(*sin),
+ ("%s: invalid length for address %p", __func__, sin));
+
error = prison_local_ip4(cred, &sin->sin_addr);
if (error)
return (error);
@@ -1372,6 +1371,11 @@
u_short lport, fport;
int error;
+ KASSERT(sin->sin_family == AF_INET,
+ ("%s: invalid address family for %p", __func__, sin));
+ KASSERT(sin->sin_len == sizeof(*sin),
+ ("%s: invalid address length for %p", __func__, sin));
+
/*
* Because a global state change doesn't actually occur here, a read
* lock is sufficient.
@@ -1382,10 +1386,6 @@
if (oinpp != NULL)
*oinpp = NULL;
- if (nam->sa_len != sizeof (*sin))
- return (EINVAL);
- if (sin->sin_family != AF_INET)
- return (EAFNOSUPPORT);
if (sin->sin_port == 0)
return (EADDRNOTAVAIL);
laddr.s_addr = *laddrp;
Index: sys/netinet/ip_divert.c
===================================================================
--- sys/netinet/ip_divert.c
+++ sys/netinet/ip_divert.c
@@ -321,6 +321,13 @@
struct ipfw_rule_ref *dt;
int error, family;
+ if (sin != NULL) {
+ if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (sin->sin_len != sizeof(*sin))
+ return (EINVAL);
+ }
+
/*
* An mbuf may hasn't come from userland, but we pretend
* that it has.
@@ -622,6 +629,8 @@
*/
if (nam->sa_family != AF_INET)
return EAFNOSUPPORT;
+ if (nam->sa_len != sizeof(struct sockaddr_in))
+ return EINVAL;
((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY;
INP_INFO_WLOCK(&V_divcbinfo);
INP_WLOCK(inp);
Index: sys/netinet/raw_ip.c
===================================================================
--- sys/netinet/raw_ip.c
+++ sys/netinet/raw_ip.c
@@ -996,6 +996,8 @@
struct inpcb *inp;
int error;
+ if (nam->sa_family != AF_INET)
+ return (EAFNOSUPPORT);
if (nam->sa_len != sizeof(*addr))
return (EINVAL);
@@ -1070,6 +1072,7 @@
{
struct inpcb *inp;
u_long dst;
+ int error;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("rip_send: inp == NULL"));
@@ -1084,9 +1087,16 @@
}
dst = inp->inp_faddr.s_addr; /* Unlocked read. */
} else {
- if (nam == NULL) {
+ error = 0;
+ if (nam == NULL)
+ error = ENOTCONN;
+ else if (nam->sa_family != AF_INET)
+ error = EAFNOSUPPORT;
+ else if (nam->sa_len != sizeof(struct sockaddr_in))
+ error = EINVAL;
+ if (error != 0) {
m_freem(m);
- return (ENOTCONN);
+ return (error);
}
dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr;
}
Index: sys/netinet/sctp_usrreq.c
===================================================================
--- sys/netinet/sctp_usrreq.c
+++ sys/netinet/sctp_usrreq.c
@@ -598,29 +598,27 @@
((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))) {
goto connected_type;
- } else if (addr == NULL) {
+ }
+
+ error = 0;
+ if (addr == NULL) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ);
error = EDESTADDRREQ;
- sctp_m_freem(m);
- if (control) {
- sctp_m_freem(control);
- control = NULL;
- }
- return (error);
+ } else if (addr->sa_family != AF_INET) {
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
+ error = EAFNOSUPPORT;
+ } else if (addr->sa_len != sizeof(struct sockaddr_in)) {
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
}
-#ifdef INET6
- if (addr->sa_family != AF_INET) {
- /* must be a v4 address! */
- SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ);
+ if (error != 0) {
sctp_m_freem(m);
if (control) {
sctp_m_freem(control);
control = NULL;
}
- error = EDESTADDRREQ;
return (error);
}
-#endif /* INET6 */
connected_type:
/* now what about control */
if (control) {
Index: sys/netinet/tcp_usrreq.c
===================================================================
--- sys/netinet/tcp_usrreq.c
+++ sys/netinet/tcp_usrreq.c
@@ -321,14 +321,16 @@
struct sockaddr_in *sinp;
sinp = (struct sockaddr_in *)nam;
- if (nam->sa_len != sizeof (*sinp))
+ if (nam->sa_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (nam->sa_len != sizeof(*sinp))
return (EINVAL);
+
/*
* Must check for multicast addresses and disallow binding
* to them.
*/
- if (sinp->sin_family == AF_INET &&
- IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
+ if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
return (EAFNOSUPPORT);
TCPDEBUG0;
@@ -364,14 +366,16 @@
u_char vflagsav;
sin6 = (struct sockaddr_in6 *)nam;
- if (nam->sa_len != sizeof (*sin6))
+ if (nam->sa_family != AF_INET6)
+ return (EAFNOSUPPORT);
+ if (nam->sa_len != sizeof(*sin6))
return (EINVAL);
+
/*
* Must check for multicast addresses and disallow binding
* to them.
*/
- if (sin6->sin6_family == AF_INET6 &&
- IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
+ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
return (EAFNOSUPPORT);
TCPDEBUG0;
@@ -542,16 +546,17 @@
struct sockaddr_in *sinp;
sinp = (struct sockaddr_in *)nam;
+ if (nam->sa_family != AF_INET)
+ return (EAFNOSUPPORT);
if (nam->sa_len != sizeof (*sinp))
return (EINVAL);
+
/*
* Must disallow TCP ``connections'' to multicast addresses.
*/
- if (sinp->sin_family == AF_INET
- && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
+ if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
return (EAFNOSUPPORT);
- if ((sinp->sin_family == AF_INET) &&
- (ntohl(sinp->sin_addr.s_addr) == INADDR_BROADCAST))
+ if (ntohl(sinp->sin_addr.s_addr) == INADDR_BROADCAST)
return (EACCES);
if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
return (error);
@@ -606,13 +611,15 @@
TCPDEBUG0;
sin6 = (struct sockaddr_in6 *)nam;
+ if (nam->sa_family != AF_INET6)
+ return (EAFNOSUPPORT);
if (nam->sa_len != sizeof (*sin6))
return (EINVAL);
+
/*
* Must disallow TCP ``connections'' to multicast addresses.
*/
- if (sin6->sin6_family == AF_INET6
- && IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
+ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
return (EAFNOSUPPORT);
inp = sotoinpcb(so);
Index: sys/netinet/udp_usrreq.c
===================================================================
--- sys/netinet/udp_usrreq.c
+++ sys/netinet/udp_usrreq.c
@@ -1626,6 +1626,12 @@
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp_bind: inp == NULL"));
+
+ if (nam->sa_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (nam->sa_len != sizeof(struct sockaddr_in))
+ return (EINVAL);
+
INP_WLOCK(inp);
INP_HASH_WLOCK(pcbinfo);
error = in_pcbbind(inp, nam, td->td_ucred);
@@ -1666,12 +1672,18 @@
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp_connect: inp == NULL"));
+
+ sin = (struct sockaddr_in *)nam;
+ if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (sin->sin_len != sizeof(*sin))
+ return (EINVAL);
+
INP_WLOCK(inp);
if (inp->inp_faddr.s_addr != INADDR_ANY) {
INP_WUNLOCK(inp);
return (EISCONN);
}
- sin = (struct sockaddr_in *)nam;
error = prison_remote_ip4(td->td_ucred, &sin->sin_addr);
if (error != 0) {
INP_WUNLOCK(inp);
@@ -1741,9 +1753,23 @@
struct mbuf *control, struct thread *td)
{
struct inpcb *inp;
+ int error;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp_send: inp == NULL"));
+
+ if (addr != NULL) {
+ error = 0;
+ if (addr->sa_family != AF_INET)
+ error = EAFNOSUPPORT;
+ else if (addr->sa_len != sizeof(struct sockaddr_in))
+ error = EINVAL;
+ if (__predict_false(error != 0)) {
+ m_freem(control);
+ m_freem(m);
+ return (error);
+ }
+ }
return (udp_output(inp, m, addr, control, td, flags));
}
#endif /* INET */
Index: sys/netinet6/in6_pcb.c
===================================================================
--- sys/netinet6/in6_pcb.c
+++ sys/netinet6/in6_pcb.c
@@ -146,13 +146,10 @@
return (error);
} else {
sin6 = (struct sockaddr_in6 *)nam;
- if (nam->sa_len != sizeof(*sin6))
- return (EINVAL);
- /*
- * family check.
- */
- if (nam->sa_family != AF_INET6)
- return (EAFNOSUPPORT);
+ KASSERT(sin6->sin6_family == AF_INET6,
+ ("%s: invalid address family for %p", __func__, sin6));
+ KASSERT(sin6->sin6_len == sizeof(*sin6),
+ ("%s: invalid address length for %p", __func__, sin6));
if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0)
return(error);
@@ -345,10 +342,9 @@
* have forced minor changes in every protocol).
*/
static int
-in6_pcbladdr(struct inpcb *inp, struct sockaddr *nam,
+in6_pcbladdr(struct inpcb *inp, struct sockaddr_in6 *sin6,
struct in6_addr *plocal_addr6)
{
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
int error = 0;
int scope_ambiguous = 0;
struct in6_addr in6a;
@@ -357,10 +353,6 @@
INP_WLOCK_ASSERT(inp);
INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo); /* XXXRW: why? */
- if (nam->sa_len != sizeof (*sin6))
- return (EINVAL);
- if (sin6->sin6_family != AF_INET6)
- return (EAFNOSUPPORT);
if (sin6->sin6_port == 0)
return (EADDRNOTAVAIL);
@@ -421,6 +413,11 @@
struct sockaddr_in6 laddr6;
int error;
+ KASSERT(sin6->sin6_family == AF_INET6,
+ ("%s: invalid address family for %p", __func__, sin6));
+ KASSERT(sin6->sin6_len == sizeof(*sin6),
+ ("%s: invalid address length for %p", __func__, sin6));
+
bzero(&laddr6, sizeof(laddr6));
laddr6.sin6_family = AF_INET6;
@@ -442,7 +439,7 @@
* Call inner routine, to assign local interface address.
* in6_pcbladdr() may automatically fill in sin6_scope_id.
*/
- if ((error = in6_pcbladdr(inp, nam, &laddr6.sin6_addr)) != 0)
+ if ((error = in6_pcbladdr(inp, sin6, &laddr6.sin6_addr)) != 0)
return (error);
if (in6_pcblookup_hash_locked(pcbinfo, &sin6->sin6_addr,
Index: sys/netinet6/raw_ip6.c
===================================================================
--- sys/netinet6/raw_ip6.c
+++ sys/netinet6/raw_ip6.c
@@ -760,6 +760,8 @@
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("rip6_bind: inp == NULL"));
+ if (nam->sa_family != AF_INET6)
+ return (EAFNOSUPPORT);
if (nam->sa_len != sizeof(*addr))
return (EINVAL);
if ((error = prison_check_ip6(td->td_ucred, &addr->sin6_addr)) != 0)
@@ -891,6 +893,10 @@
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);
Index: sys/netinet6/sctp6_usrreq.c
===================================================================
--- sys/netinet6/sctp6_usrreq.c
+++ sys/netinet6/sctp6_usrreq.c
@@ -676,11 +676,8 @@
struct mbuf *control, struct thread *p)
{
struct sctp_inpcb *inp;
-
-#ifdef INET
struct sockaddr_in6 *sin6;
-#endif /* INET */
- /* No SPL needed since sctp_output does this */
+ int error;
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
@@ -709,22 +706,33 @@
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EDESTADDRREQ);
return (EDESTADDRREQ);
}
-#ifdef INET
+ error = 0;
sin6 = (struct sockaddr_in6 *)addr;
- if (SCTP_IPV6_V6ONLY(inp)) {
+ if (addr->sa_family != AF_INET6) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EAFNOSUPPORT);
+ error = EAFNOSUPPORT;
+ } else if (addr->sa_len != sizeof(*sin6)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+#ifdef INET
+ else if (SCTP_IPV6_V6ONLY(inp) && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
/*
* if IPV6_V6ONLY flag, we discard datagrams destined to a
* v4 addr or v4-mapped addr
*/
- if (addr->sa_family == AF_INET) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
- return (EINVAL);
- }
- if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
- return (EINVAL);
- }
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+#endif
+ if (error != 0) {
+ SCTP_RELEASE_PKT(m);
+ if (control)
+ SCTP_RELEASE_PKT(control);
+ return (error);
}
+
+#ifdef INET
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
struct sockaddr_in sin;
Index: sys/netinet6/send.c
===================================================================
--- sys/netinet6/send.c
+++ sys/netinet6/send.c
@@ -231,6 +231,14 @@
__func__, so, V_send_so));
sendsrc = (struct sockaddr_send *)nam;
+ if (sendsrc->send_family != AF_INET6) {
+ error = EAFNOSUPPORT;
+ goto err;
+ }
+ if (sendsrc->send_len != sizeof(*sendsrc)) {
+ error = EINVAL;
+ goto err;
+ }
ifp = ifnet_byindex_ref(sendsrc->send_ifidx);
if (ifp == NULL) {
error = ENETUNREACH;
Index: sys/netinet6/udp6_usrreq.c
===================================================================
--- sys/netinet6/udp6_usrreq.c
+++ sys/netinet6/udp6_usrreq.c
@@ -1091,6 +1091,11 @@
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));
+ if (nam->sa_family != AF_INET6)
+ return (EAFNOSUPPORT);
+ if (nam->sa_len != sizeof(struct sockaddr_in6))
+ return (EINVAL);
+
INP_WLOCK(inp);
INP_HASH_WLOCK(pcbinfo);
vflagsav = inp->inp_vflag;
@@ -1176,9 +1181,14 @@
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
inp = sotoinpcb(so);
- sin6 = (struct sockaddr_in6 *)nam;
KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
+ sin6 = (struct sockaddr_in6 *)nam;
+ if (sin6->sin6_family != AF_INET6)
+ return (EAFNOSUPPORT);
+ if (sin6->sin6_len != sizeof(*sin6))
+ return (EINVAL);
+
/*
* XXXRW: Need to clarify locking of v4/v6 flags.
*/
Index: sys/netipsec/keysock.c
===================================================================
--- sys/netipsec/keysock.c
+++ sys/netipsec/keysock.c
@@ -322,7 +322,7 @@
static int
key_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
- return EINVAL;
+ return EINVAL;
}
/*
Index: sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
===================================================================
--- sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
+++ sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
@@ -519,9 +519,9 @@
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)nam;
- if (nam->sa_len != sizeof (*sin))
- return (EINVAL);
if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (nam->sa_len != sizeof(*sin))
return (EINVAL);
if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
return (EAFNOSUPPORT);
@@ -932,6 +932,17 @@
int error;
int cnt;
+ if (nam != NULL) {
+ if (nam->sa_family != AF_INET) {
+ m_freem(m);
+ return (EAFNOSUPPORT);
+ }
+ if (nam->sa_len != sizeof(struct sockaddr_in)) {
+ m_freem(m);
+ return (EINVAL);
+ }
+ }
+
error = 0;
ssk = sdp_sk(so);
KASSERT(m->m_flags & M_PKTHDR,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 25, 8:50 AM (18 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17778354
Default Alt Text
D29519.id86631.diff (16 KB)
Attached To
Mode
D29519: Add missing sockaddr length and family validation to various protocols
Attached
Detach File
Event Timeline
Log In to Comment