From owner-svn-src-all@FreeBSD.ORG Thu Sep 15 08:49:54 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A94EE106564A; Thu, 15 Sep 2011 08:49:54 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 97F968FC0A; Thu, 15 Sep 2011 08:49:54 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p8F8nsXT064639; Thu, 15 Sep 2011 08:49:54 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p8F8nssF064633; Thu, 15 Sep 2011 08:49:54 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201109150849.p8F8nssF064633@svn.freebsd.org> From: Michael Tuexen Date: Thu, 15 Sep 2011 08:49:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225571 - head/sys/netinet X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Sep 2011 08:49:54 -0000 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);