summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2014-01-07 23:51:41 +0000
committertuexen <tuexen@FreeBSD.org>2014-01-07 23:51:41 +0000
commitc4f2c365c9e2791fc74b817c70f98dc2846e5cbd (patch)
tree08f533859e3ba8e260b03630fd02138405478d98 /lib
parent624cda0839e8304fdd1091289e62b9caab51b889 (diff)
downloadFreeBSD-src-c4f2c365c9e2791fc74b817c70f98dc2846e5cbd.zip
FreeBSD-src-c4f2c365c9e2791fc74b817c70f98dc2846e5cbd.tar.gz
MFC r260257:
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/net/sctp_sys_calls.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c
index fda9676..a7da95c 100644
--- a/lib/libc/net/sctp_sys_calls.c
+++ b/lib/libc/net/sctp_sys_calls.c
@@ -233,19 +233,11 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags)
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 *addrs, int addrcnt, int flags)
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);
OpenPOWER on IntegriCloud