diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-04-05 12:05:18 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-04-05 12:05:18 +0000 |
commit | 68aa949ea1a29ae26140b73702400eae92ab9a6f (patch) | |
tree | c9fdf4465cfce8b5b0ffd1d17fc4a588874c6207 /usr/src/lib/libnsl | |
parent | f5823ecdf8884e3132129eab9723e0ac848d8322 (diff) | |
parent | a48d81205a4295fd3f979e8ab98212a784b8f9e9 (diff) | |
download | illumos-joyent-68aa949ea1a29ae26140b73702400eae92ab9a6f.tar.gz |
[illumos-gate merge]
commit a48d81205a4295fd3f979e8ab98212a784b8f9e9
6829 Would like boot_time and init_pid for zones exposed to GZ kstats
commit 5dee1fa64fd5ddfe4221aaa94bc981e0b9d78b92
6771 end-of-loop code not reached in common/dnssd_clientstub.c
commit 03b59f7842b50eda32f941744a5d94a55e47ba26
5868 Make checks in inet_matchaddr() more robust
commit 043dd586a30a181228ae6d69b6b80c02f2277df7
5866 "wrong authentication" messages with root=@0.0.0.0/0 set, result in loss of client access
commit d1e631af56641f21cde1f1efe3a9623ff9d6ee7c
6853 built in fonts are exposing internal data
commit 9468939ef8704ee9aba7596c1e9ff9b059109cac
6823 need per-zone kstat to track pageins
Conflicts:
usr/src/uts/common/sys/zone.h
usr/src/uts/common/os/zone.c
Diffstat (limited to 'usr/src/lib/libnsl')
-rw-r--r-- | usr/src/lib/libnsl/common/llib-lnsl | 4 | ||||
-rw-r--r-- | usr/src/lib/libnsl/nss/inet_matchaddr.c | 98 |
2 files changed, 73 insertions, 29 deletions
diff --git a/usr/src/lib/libnsl/common/llib-lnsl b/usr/src/lib/libnsl/common/llib-lnsl index 582eecef95..46f74824eb 100644 --- a/usr/src/lib/libnsl/common/llib-lnsl +++ b/usr/src/lib/libnsl/common/llib-lnsl @@ -23,7 +23,7 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. */ @@ -440,7 +440,7 @@ void endrpcent(void); struct rpcent *getrpcent_r(struct rpcent *result, char *buffer, int buflen); /* inet_matchaddr.c */ -boolean_t inet_matchaddr(const void *, const char *); +int inet_matchaddr(const void *, const char *); /* inet_ntop.c */ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); diff --git a/usr/src/lib/libnsl/nss/inet_matchaddr.c b/usr/src/lib/libnsl/nss/inet_matchaddr.c index 566c1ae1ad..4a510ea01b 100644 --- a/usr/src/lib/libnsl/nss/inet_matchaddr.c +++ b/usr/src/lib/libnsl/nss/inet_matchaddr.c @@ -7,8 +7,10 @@ * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. - * - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ + +/* + * Copyright 2016 Nexenta Systems, Inc. */ /* @@ -24,6 +26,14 @@ * IPv6: * [IPv6] * [IPv6]/prefix + * + * Return values: + * + * 0 mismatch + * 1 match + * -1 error occured, caller should check errno: + * EINVAL access list entry is invalid + * ENOMEM failed to allocate memory */ #include <sys/socket.h> @@ -34,21 +44,24 @@ #include <netinet/in.h> #include <ctype.h> -#include <err.h> +#include <errno.h> #include <netdb.h> #include <stdlib.h> #include <strings.h> - -boolean_t +int inet_matchaddr(const void *sa, const char *name) { - boolean_t ret = B_FALSE; + int ret = -1; char *lname, *mp, *p; + char *ep; + int serrno = errno; uint32_t claddr4 = 0; - if ((p = lname = strdup(name)) == NULL) - err(1, "strdup"); + if ((p = lname = strdup(name)) == NULL) { + errno = ENOMEM; + return (-1); + } if ((mp = strchr(p, '/')) != NULL) *mp++ = '\0'; @@ -56,7 +69,6 @@ inet_matchaddr(const void *sa, const char *name) switch (((struct sockaddr_in *)sa)->sin_family) { case AF_INET6: { char *pp; - int prefix6; ipaddr_t ipaddr4; struct in6_addr hcaddr6; struct in6_addr *claddr6 = @@ -64,28 +76,43 @@ inet_matchaddr(const void *sa, const char *name) if (!IN6_IS_ADDR_V4MAPPED(claddr6)) { /* IPv6 address */ - if ((p = strchr(p, '[')) == NULL) + if (*p != '[') { + errno = EINVAL; break; + } p++; - if ((pp = strchr(p, ']')) == NULL) + if ((pp = strchr(p, ']')) == NULL || + (mp != NULL && pp != mp - 2) || + (mp == NULL && *(pp + 1) != '\0')) { + errno = EINVAL; break; + } *pp = '\0'; - if (inet_pton(AF_INET6, p, &hcaddr6) != 1) + if (inet_pton(AF_INET6, p, &hcaddr6) != 1) { + errno = EINVAL; break; + } if (mp != NULL) { /* Match only first prefix bits */ - if ((prefix6 = (int)strtol(mp, - (char **)NULL, 10)) == 0) + long prefix6; + + errno = 0; + prefix6 = strtol(mp, &ep, 10); + if (errno != 0 || prefix6 < 0 || + prefix6 > 128 || *ep != '\0') { + errno = EINVAL; break; + } ret = IN6_ARE_PREFIXEDADDR_EQUAL(claddr6, - &hcaddr6, prefix6); + &hcaddr6, prefix6) ? 1 : 0; break; } else { /* No prefix, exact match */ - ret = IN6_ARE_ADDR_EQUAL(claddr6, &hcaddr6); + ret = IN6_ARE_ADDR_EQUAL(claddr6, + &hcaddr6) ? 1 : 0; break; } } else { @@ -96,30 +123,45 @@ inet_matchaddr(const void *sa, const char *name) /*FALLTHROUGH*/ } case AF_INET: { - int bits, i; + int i; uint32_t hcaddr4 = 0, mask4; - if (claddr4 == 0) + if (claddr4 == 0) { claddr4 = ntohl( ((struct sockaddr_in *)sa)->sin_addr.s_addr); + } for (i = 0; i < 4; i++) { - hcaddr4 |= (int)strtol(p, (char **)NULL, 10) << - ((3 - i) * 8); - if ((p = strchr(p, '.')) == NULL) + long qaddr4; + + errno = 0; + qaddr4 = strtol(p, &ep, 10); + if (errno != 0 || qaddr4 < 0 || qaddr4 > 255 || + (*ep != '.' && *ep != '\0')) { + errno = EINVAL; break; - p++; + } + hcaddr4 |= qaddr4 << ((3 - i) * 8); + if (*ep == '\0') + break; + p = ep + 1; } - if (hcaddr4 == 0) + if (errno != 0) break; if (mp != NULL) { /* Mask is specified explicitly */ - if ((bits = (int)strtol(mp, (char **)NULL, 10)) == 0) + long mb; + + errno = 0; + mb = strtol(mp, &ep, 10); + if (errno != 0 || mb < 0 || mb > 32 || *ep != '\0') { + errno = EINVAL; break; - mask4 = bits ? ~0 << ((sizeof (struct in_addr) * NBBY) - - bits) : 0; + } + mask4 = mb ? ~0 << ((sizeof (struct in_addr) * NBBY) + - mb) : 0; hcaddr4 &= mask4; } else { /* @@ -139,12 +181,14 @@ inet_matchaddr(const void *sa, const char *name) mask4 = IN_CLASSE_NET; } - ret = ((claddr4 & mask4) == hcaddr4); + ret = ((claddr4 & mask4) == hcaddr4) ? 1 : 0; break; } } free(lname); + if (ret != -1) + errno = serrno; return (ret); } |