Author: tuexen
Date: Thu Feb 18 21:05:04 2016
New Revision: 295771
URL: https://svnweb.freebsd.org/changeset/base/295771

Log:
  Fix reporting of mapped addressed in getpeername() and getsockname() for
  IPv6 SCTP sockets.
  This bugs were found because of an issue reported by PVS / D5245.

Modified:
  head/sys/netinet6/sctp6_usrreq.c

Modified: head/sys/netinet6/sctp6_usrreq.c
==============================================================================
--- head/sys/netinet6/sctp6_usrreq.c    Thu Feb 18 20:37:12 2016        
(r295770)
+++ head/sys/netinet6/sctp6_usrreq.c    Thu Feb 18 21:05:04 2016        
(r295771)
@@ -1008,7 +1008,9 @@ sctp6_getaddr(struct socket *so, struct 
 
                        stcb = LIST_FIRST(&inp->sctp_asoc_list);
                        if (stcb == NULL) {
-                               goto notConn6;
+                               SCTP_INP_RUNLOCK(inp);
+                               SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP6_USRREQ, ENOENT);
+                               return (ENOENT);
                        }
                        fnd = 0;
                        sin_a6 = NULL;
@@ -1025,7 +1027,9 @@ sctp6_getaddr(struct socket *so, struct 
                        }
                        if ((!fnd) || (sin_a6 == NULL)) {
                                /* punt */
-                               goto notConn6;
+                               SCTP_INP_RUNLOCK(inp);
+                               SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP6_USRREQ, ENOENT);
+                               return (ENOENT);
                        }
                        vrf_id = inp->def_vrf_id;
                        sctp_ifa = sctp_source_address_selection(inp, stcb, 
(sctp_route_t *) & net->ro, net, 0, vrf_id);
@@ -1034,7 +1038,6 @@ sctp6_getaddr(struct socket *so, struct 
                        }
                } else {
                        /* For the bound all case you get back 0 */
-       notConn6:
                        memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));
                }
        } else {
@@ -1135,10 +1138,6 @@ sctp6_peeraddr(struct socket *so, struct
 static int
 sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
 {
-#ifdef INET
-       struct sockaddr *addr;
-
-#endif
        struct in6pcb *inp6 = sotoin6pcb(so);
        int error;
 
@@ -1150,19 +1149,21 @@ sctp6_in6getaddr(struct socket *so, stru
        error = sctp6_getaddr(so, nam);
 #ifdef INET
        if (error) {
+               struct sockaddr_in6 *sin6;
+
                /* try v4 next if v6 failed */
                error = sctp_ingetaddr(so, nam);
                if (error) {
                        return (error);
                }
-               addr = *nam;
-               /* if I'm V6ONLY, convert it to v4-mapped */
-               if (SCTP_IPV6_V6ONLY(inp6)) {
-                       struct sockaddr_in6 sin6;
-
-                       in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
-                       memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
-               }
+               SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
+               if (sin6 == NULL) {
+                       SCTP_FREE_SONAME(*nam);
+                       return (ENOMEM);
+               }
+               in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
+               SCTP_FREE_SONAME(*nam);
+               *nam = (struct sockaddr *)sin6;
        }
 #endif
        return (error);
@@ -1172,10 +1173,6 @@ sctp6_in6getaddr(struct socket *so, stru
 static int
 sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
 {
-#ifdef INET
-       struct sockaddr *addr;
-
-#endif
        struct in6pcb *inp6 = sotoin6pcb(so);
        int error;
 
@@ -1187,19 +1184,21 @@ sctp6_getpeeraddr(struct socket *so, str
        error = sctp6_peeraddr(so, nam);
 #ifdef INET
        if (error) {
+               struct sockaddr_in6 *sin6;
+
                /* try v4 next if v6 failed */
                error = sctp_peeraddr(so, nam);
                if (error) {
                        return (error);
                }
-               addr = *nam;
-               /* if I'm V6ONLY, convert it to v4-mapped */
-               if (SCTP_IPV6_V6ONLY(inp6)) {
-                       struct sockaddr_in6 sin6;
-
-                       in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
-                       memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
-               }
+               SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
+               if (sin6 == NULL) {
+                       SCTP_FREE_SONAME(*nam);
+                       return (ENOMEM);
+               }
+               in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
+               SCTP_FREE_SONAME(*nam);
+               *nam = (struct sockaddr *)sin6;
        }
 #endif
        return (error);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to