Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Feb 2012 23:00:24 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r231463 - stable/8/sys/netinet
Message-ID:  <201202102300.q1AN0O0r000331@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Fri Feb 10 23:00:24 2012
New Revision: 231463
URL: http://svn.freebsd.org/changeset/base/231463

Log:
  MFC r225571:
  Make sure that SCTP rejects broadcast, multicast and wildcard addresses
  as remote addresses.

Modified:
  stable/8/sys/netinet/sctp_asconf.c
  stable/8/sys/netinet/sctp_output.c
  stable/8/sys/netinet/sctp_pcb.c
  stable/8/sys/netinet/sctp_usrreq.c
  stable/8/sys/netinet/sctputil.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/sys/netinet/sctp_asconf.c
==============================================================================
--- stable/8/sys/netinet/sctp_asconf.c	Fri Feb 10 22:57:50 2012	(r231462)
+++ stable/8/sys/netinet/sctp_asconf.c	Fri Feb 10 23:00:24 2012	(r231463)
@@ -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: stable/8/sys/netinet/sctp_output.c
==============================================================================
--- stable/8/sys/netinet/sctp_output.c	Fri Feb 10 22:57:50 2012	(r231462)
+++ stable/8/sys/netinet/sctp_output.c	Fri Feb 10 23:00:24 2012	(r231463)
@@ -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: stable/8/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/8/sys/netinet/sctp_pcb.c	Fri Feb 10 22:57:50 2012	(r231462)
+++ stable/8/sys/netinet/sctp_pcb.c	Fri Feb 10 23:00:24 2012	(r231463)
@@ -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: stable/8/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/8/sys/netinet/sctp_usrreq.c	Fri Feb 10 22:57:50 2012	(r231462)
+++ stable/8/sys/netinet/sctp_usrreq.c	Fri Feb 10 23:00:24 2012	(r231463)
@@ -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: stable/8/sys/netinet/sctputil.c
==============================================================================
--- stable/8/sys/netinet/sctputil.c	Fri Feb 10 22:57:50 2012	(r231462)
+++ stable/8/sys/netinet/sctputil.c	Fri Feb 10 23:00:24 2012	(r231463)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202102300.q1AN0O0r000331>