svn commit: r260257 - head/lib/libc/net

Michael Tuexen tuexen at FreeBSD.org
Sat Jan 4 11:40:00 UTC 2014


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);


More information about the svn-src-all mailing list