svn commit: r225571 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Thu Sep 15 08:49:54 UTC 2011
Author: tuexen
Date: Thu Sep 15 08:49:54 2011
New Revision: 225571
URL: http://svn.freebsd.org/changeset/base/225571
Log:
Make sure that SCTP rejects broadcast, multicast and wildcard addresses
as remote addresses.
Approved by: re
MFC after: 1 month.
Modified:
head/sys/netinet/sctp_asconf.c
head/sys/netinet/sctp_output.c
head/sys/netinet/sctp_pcb.c
head/sys/netinet/sctp_usrreq.c
head/sys/netinet/sctputil.c
Modified: head/sys/netinet/sctp_asconf.c
==============================================================================
--- head/sys/netinet/sctp_asconf.c Thu Sep 15 08:42:06 2011 (r225570)
+++ head/sys/netinet/sctp_asconf.c Thu Sep 15 08:49:54 2011 (r225571)
@@ -207,6 +207,7 @@ sctp_process_asconf_add_ip(struct mbuf *
uint16_t param_type, param_length, aparam_length;
struct sockaddr *sa;
int zero_address = 0;
+ int bad_address = 0;
#ifdef INET
struct sockaddr_in *sin;
@@ -239,6 +240,10 @@ sctp_process_asconf_add_ip(struct mbuf *
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_port = stcb->rport;
sin->sin_addr.s_addr = v4addr->addr;
+ if ((sin->sin_addr.s_addr == INADDR_BROADCAST) ||
+ IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
+ bad_address = 1;;
+ }
if (sin->sin_addr.s_addr == INADDR_ANY)
zero_address = 1;
SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
@@ -259,6 +264,9 @@ sctp_process_asconf_add_ip(struct mbuf *
sin6->sin6_port = stcb->rport;
memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
sizeof(struct in6_addr));
+ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
+ bad_address = 1;
+ }
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
zero_address = 1;
SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
@@ -266,12 +274,8 @@ sctp_process_asconf_add_ip(struct mbuf *
break;
#endif
default:
- /*
- * XXX: Is this the correct error cause? Maybe
- * SCTP_CAUSE_INVALID_PARAM is a better choice.
- */
m_reply = sctp_asconf_error_response(aph->correlation_id,
- SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
+ SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
aparam_length);
return m_reply;
} /* end switch */
@@ -285,7 +289,11 @@ sctp_process_asconf_add_ip(struct mbuf *
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
}
/* add the address */
- if (sctp_add_remote_addr(stcb, sa, &net, SCTP_DONOT_SETSCOPE,
+ if (bad_address) {
+ m_reply = sctp_asconf_error_response(aph->correlation_id,
+ SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
+ aparam_length);
+ } else if (sctp_add_remote_addr(stcb, sa, &net, SCTP_DONOT_SETSCOPE,
SCTP_ADDR_DYNAMIC_ADDED) != 0) {
SCTPDBG(SCTP_DEBUG_ASCONF1,
"process_asconf_add_ip: error adding address\n");
Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c Thu Sep 15 08:42:06 2011 (r225570)
+++ head/sys/netinet/sctp_output.c Thu Sep 15 08:49:54 2011 (r225571)
@@ -3541,7 +3541,7 @@ sctp_process_cmsgs_for_init(struct sctp_
(sin.sin_addr.s_addr == INADDR_BROADCAST) ||
IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
*error = EINVAL;
- return (-1);
+ return (1);
}
if (sctp_add_remote_addr(stcb, (struct sockaddr *)&sin, NULL,
SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
@@ -3564,7 +3564,7 @@ sctp_process_cmsgs_for_init(struct sctp_
if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr) ||
IN6_IS_ADDR_MULTICAST(&sin6.sin6_addr)) {
*error = EINVAL;
- return (-1);
+ return (1);
}
#ifdef INET
if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
@@ -3573,7 +3573,7 @@ sctp_process_cmsgs_for_init(struct sctp_
(sin.sin_addr.s_addr == INADDR_BROADCAST) ||
IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
*error = EINVAL;
- return (-1);
+ return (1);
}
if (sctp_add_remote_addr(stcb, (struct sockaddr *)&sin, NULL,
SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c Thu Sep 15 08:42:06 2011 (r225570)
+++ head/sys/netinet/sctp_pcb.c Thu Sep 15 08:49:54 2011 (r225571)
@@ -4332,7 +4332,10 @@ sctp_aloc_assoc(struct sctp_inpcb *inp,
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)firstaddr;
- if ((sin->sin_port == 0) || (sin->sin_addr.s_addr == 0)) {
+ if ((ntohs(sin->sin_port) == 0) ||
+ (sin->sin_addr.s_addr == INADDR_ANY) ||
+ (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
+ IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
/* Invalid address */
SCTP_INP_RUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
@@ -4349,8 +4352,9 @@ sctp_aloc_assoc(struct sctp_inpcb *inp,
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)firstaddr;
- if ((sin6->sin6_port == 0) ||
- (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
+ if ((ntohs(sin6->sin6_port) == 0) ||
+ IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
+ IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
/* Invalid address */
SCTP_INP_RUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c Thu Sep 15 08:42:06 2011 (r225570)
+++ head/sys/netinet/sctp_usrreq.c Thu Sep 15 08:49:54 2011 (r225571)
@@ -560,7 +560,7 @@ sctp_bind(struct socket *so, struct sock
struct sctp_inpcb *inp = NULL;
int error;
-#ifdef INET6
+#ifdef INET
if (addr && addr->sa_family != AF_INET) {
/* must be a v4 address! */
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c Thu Sep 15 08:42:06 2011 (r225570)
+++ head/sys/netinet/sctputil.c Thu Sep 15 08:49:54 2011 (r225571)
@@ -6080,6 +6080,15 @@ sctp_connectx_helper_add(struct sctp_tcb
struct sockaddr *sa;
size_t incr = 0;
+#ifdef INET
+ struct sockaddr_in *sin;
+
+#endif
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+
+#endif
+
sa = addr;
inp = stcb->sctp_ep;
*error = 0;
@@ -6088,6 +6097,15 @@ sctp_connectx_helper_add(struct sctp_tcb
#ifdef INET
case AF_INET:
incr = sizeof(struct sockaddr_in);
+ sin = (struct sockaddr_in *)sa;
+ if ((sin->sin_addr.s_addr == INADDR_ANY) ||
+ (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
+ IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
+ *error = EINVAL;
+ goto out_now;
+ }
if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
/* assoc gone no un-lock */
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
@@ -6101,6 +6119,14 @@ sctp_connectx_helper_add(struct sctp_tcb
#ifdef INET6
case AF_INET6:
incr = sizeof(struct sockaddr_in6);
+ sin6 = (struct sockaddr_in6 *)sa;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
+ IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
+ *error = EINVAL;
+ goto out_now;
+ }
if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
/* assoc gone no un-lock */
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
More information about the svn-src-all
mailing list