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>