Author: tuexen
Date: Sat Jan  4 11:39:59 2014
New Revision: 260257
URL: http://svnweb.freebsd.org/changeset/base/260257

Log:
  Fix several bugs in sctp_bindx():
  * Set errno to EAFNOSUPPORT if an address is provided which is neither
    AF_INET nor AF_INET6.
  * Don't modify the arguments.
  * Don't smash the stack when provided with a non-zero port.
  * Handle the case correctly where the first address provided is
    an IPv6 address.
  
  MFC after: 3 days

Modified:
  head/lib/libc/net/sctp_sys_calls.c

Modified: head/lib/libc/net/sctp_sys_calls.c
==============================================================================
--- head/lib/libc/net/sctp_sys_calls.c  Sat Jan  4 10:19:21 2014        
(r260256)
+++ head/lib/libc/net/sctp_sys_calls.c  Sat Jan  4 11:39:59 2014        
(r260257)
@@ -233,19 +233,11 @@ sctp_bindx(int sd, struct sockaddr *addr
                        break;
                default:
                        /* Invalid address family specified. */
-                       errno = EINVAL;
+                       errno = EAFNOSUPPORT;
                        return (-1);
                }
                sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
        }
-       /*
-        * Now if there was a port mentioned, assure that the first address
-        * has that port to make sure it fails or succeeds correctly.
-        */
-       if (sport) {
-               sin = (struct sockaddr_in *)sa;
-               sin->sin_port = sport;
-       }
        argsz = sizeof(struct sctp_getaddresses) +
            sizeof(struct sockaddr_storage);
        if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) {
@@ -257,6 +249,23 @@ sctp_bindx(int sd, struct sockaddr *addr
                memset(gaddrs, 0, argsz);
                gaddrs->sget_assoc_id = 0;
                memcpy(gaddrs->addr, sa, sa->sa_len);
+               /*
+                * Now, if there was a port mentioned, assure that the first
+                * address has that port to make sure it fails or succeeds
+                * correctly.
+                */
+               if ((i == 0) && (sport != 0)) {
+                       switch (gaddrs->addr->sa_family) {
+                       case AF_INET:
+                               sin = (struct sockaddr_in *)gaddrs->addr;
+                               sin->sin_port = sport;
+                               break;
+                       case AF_INET6:
+                               sin6 = (struct sockaddr_in6 *)gaddrs->addr;
+                               sin6->sin6_port = sport;
+                               break;
+                       }
+               }
                if (setsockopt(sd, IPPROTO_SCTP, flags, gaddrs,
                    (socklen_t) argsz) != 0) {
                        free(gaddrs);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to