From 25d63f19e6d8dce36299ad2b249a2923c9327629 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 25 Jun 2007 18:58:27 +0000 Subject: [PATCH] - Fix wrong error return (the errno was being returned and not placed in errno) - Found by Weongyo Jeong - Remove two extra un-needed memset() after calloc()'s - Found by Weongyo Jeong - Tightened up parameter requirement checking on input to bindx/connectx per socket api spec. Approved by: re@freebsd.org(Ken Smith) --- lib/libc/net/sctp_sys_calls.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c index c63466a22e08..90e1fd415cea 100644 --- a/lib/libc/net/sctp_sys_calls.c +++ b/lib/libc/net/sctp_sys_calls.c @@ -185,10 +185,18 @@ sctp_connectx(int sd, const struct sockaddr *addrs, int addrcnt, /* validate all the addresses and get the size */ for (i = 0; i < addrcnt; i++) { if (at->sa_family == AF_INET) { + if (at->sa_len != sizeof(struct sockaddr_in)) { + errno = EINVAL; + return (-1); + } memcpy(cpto, at, at->sa_len); cpto = ((caddr_t)cpto + at->sa_len); len += at->sa_len; } else if (at->sa_family == AF_INET6) { + if (at->sa_len != sizeof(struct sockaddr_in6)) { + errno = EINVAL; + return (-1); + } if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)at)->sin6_addr)) { len += sizeof(struct sockaddr_in); in6_sin6_2_sin((struct sockaddr_in *)cpto, (struct sockaddr_in6 *)at); @@ -205,7 +213,8 @@ sctp_connectx(int sd, const struct sockaddr *addrs, int addrcnt, } if (len > (sizeof(buf) - sizeof(int))) { /* Never enough memory */ - return (E2BIG); + errno = E2BIG; + return (-1) } at = (struct sockaddr *)((caddr_t)at + at->sa_len); cnt++; @@ -231,7 +240,7 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags) { struct sctp_getaddresses *gaddrs; struct sockaddr *sa; - int i, sz, fam, argsz; + int i, sz, argsz; /* validate the flags */ if ((flags != SCTP_BINDX_ADD_ADDR) && @@ -251,23 +260,30 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags) errno = ENOMEM; return (-1); } - gaddrs->sget_assoc_id = 0; sa = addrs; for (i = 0; i < addrcnt; i++) { sz = sa->sa_len; - fam = sa->sa_family; - if ((fam != AF_INET) && (fam != AF_INET6)) { + if (sa->sa_family == AF_INET) { + if (sa->sa_len != sizeof(struct sockaddr_in)) + goto out_error; + } else if (sa->sa_family == AF_INET6) { + if (sa->sa_len != sizeof(struct sockaddr_in6)) + goto out_error; + } else { + /* invalid address family specified */ + out_error: free(gaddrs); errno = EINVAL; return (-1); } + memset(gaddrs, 0, argsz); + gaddrs->sget_assoc_id = 0; memcpy(gaddrs->addr, sa, sz); - if (setsockopt(sd, IPPROTO_SCTP, flags, - gaddrs, (socklen_t) argsz) != 0) { + if (setsockopt(sd, IPPROTO_SCTP, flags, gaddrs, + (socklen_t) argsz) != 0) { free(gaddrs); return (-1); } - memset(gaddrs, 0, argsz); sa = (struct sockaddr *)((caddr_t)sa + sz); } free(gaddrs); @@ -315,7 +331,6 @@ sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) errno = ENOMEM; return (-1); } - memset(addrs, 0, siz); addrs->sget_assoc_id = id; /* Now lets get the array of addresses */ if (getsockopt(sd, IPPROTO_SCTP, SCTP_GET_PEER_ADDRESSES, @@ -380,7 +395,6 @@ sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) errno = ENOMEM; return (-1); } - memset(addrs, 0, siz); addrs->sget_assoc_id = id; /* Now lets get the array of addresses */ if (getsockopt(sd, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDRESSES, addrs,