diff options
author | oshogbo <oshogbo@FreeBSD.org> | 2016-04-14 18:27:10 +0000 |
---|---|---|
committer | oshogbo <oshogbo@FreeBSD.org> | 2016-04-14 18:27:10 +0000 |
commit | b39957c360ee5bb0d9e656e636e36d475713f6cc (patch) | |
tree | 3085f25fe79435f760d8f2d477207e43cc9e0136 /tools/regression | |
parent | c3dfe54d824933b6bf801646313bf6eb06e0888f (diff) | |
download | FreeBSD-src-b39957c360ee5bb0d9e656e636e36d475713f6cc.zip FreeBSD-src-b39957c360ee5bb0d9e656e636e36d475713f6cc.tar.gz |
Set NULL to the ai_next pointer which fix cap_getaddrinfo().
Add regression test case.
PR: 195551
Submitted by: Mikhail <mp39590@gmail.com>
Approved by: pjd (mentor)
Diffstat (limited to 'tools/regression')
-rw-r--r-- | tools/regression/capsicum/libcasper/dns.c | 130 |
1 files changed, 122 insertions, 8 deletions
diff --git a/tools/regression/capsicum/libcasper/dns.c b/tools/regression/capsicum/libcasper/dns.c index eb364da..51839c1 100644 --- a/tools/regression/capsicum/libcasper/dns.c +++ b/tools/regression/capsicum/libcasper/dns.c @@ -72,6 +72,63 @@ static int ntest = 1; #define GETHOSTBYNAME2_AF_INET6 0x04 #define GETHOSTBYADDR_AF_INET 0x08 #define GETHOSTBYADDR_AF_INET6 0x10 +#define GETADDRINFO_AF_UNSPEC 0x20 +#define GETADDRINFO_AF_INET 0x40 +#define GETADDRINFO_AF_INET6 0x80 + +static bool +addrinfo_compare(struct addrinfo *ai0, struct addrinfo *ai1) +{ + struct addrinfo *at0, *at1; + + if (ai0 == NULL && ai1 == NULL) + return (true); + if (ai0 == NULL || ai1 == NULL) + return (false); + + at0 = ai0; + at1 = ai1; + while (true) { + if ((at0->ai_flags == at1->ai_flags) && + (at0->ai_family == at1->ai_family) && + (at0->ai_socktype == at1->ai_socktype) && + (at0->ai_protocol == at1->ai_protocol) && + (at0->ai_addrlen == at1->ai_addrlen) && + (memcmp(at0->ai_addr, at1->ai_addr, + at0->ai_addrlen) == 0)) { + if (at0->ai_canonname != NULL && + at1->ai_canonname != NULL) { + if (strcmp(at0->ai_canonname, + at1->ai_canonname) != 0) { + return (false); + } + } + + if (at0->ai_canonname == NULL && + at1->ai_canonname != NULL) { + return (false); + } + if (at0->ai_canonname != NULL && + at1->ai_canonname == NULL) { + return (false); + } + + if (at0->ai_next == NULL && at1->ai_next == NULL) + return (true); + if (at0->ai_next == NULL || at1->ai_next == NULL) + return (false); + + at0 = at0->ai_next; + at1 = at1->ai_next; + } else { + return (false); + } + } + + /* NOTREACHED */ + fprintf(stderr, "Dead code reached in addrinfo_compare()\n"); + exit(1); +} static bool hostent_aliases_compare(char **aliases0, char **aliases1) @@ -161,6 +218,7 @@ static unsigned int runtest(cap_channel_t *capdns) { unsigned int result; + struct addrinfo *ais, *aic, hints, *hintsp; struct hostent *hps, *hpc; struct in_addr ip4; struct in6_addr ip6; @@ -188,6 +246,55 @@ runtest(cap_channel_t *capdns) if (hostent_compare(hps, hpc)) result |= GETHOSTBYNAME2_AF_INET6; + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = 0; + hints.ai_protocol = 0; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + hintsp = &hints; + + if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) { + fprintf(stderr, + "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n", + gai_strerror(errno)); + } + if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) { + if (addrinfo_compare(ais, aic)) + result |= GETADDRINFO_AF_UNSPEC; + freeaddrinfo(ais); + freeaddrinfo(aic); + } + + hints.ai_family = AF_INET; + if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) { + fprintf(stderr, + "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n", + gai_strerror(errno)); + } + if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) { + if (addrinfo_compare(ais, aic)) + result |= GETADDRINFO_AF_INET; + freeaddrinfo(ais); + freeaddrinfo(aic); + } + + hints.ai_family = AF_INET6; + if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) { + fprintf(stderr, + "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n", + gai_strerror(errno)); + } + if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) { + if (addrinfo_compare(ais, aic)) + result |= GETADDRINFO_AF_INET6; + freeaddrinfo(ais); + freeaddrinfo(aic); + } + /* * 8.8.178.135 is IPv4 address of freefall.freebsd.org * as of 27 October 2013. @@ -238,7 +345,8 @@ main(void) CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 | - GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6)); + GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6)); /* * Allow: @@ -258,7 +366,8 @@ main(void) CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 | - GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6)); + GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6)); cap_close(capdns); @@ -310,7 +419,8 @@ main(void) CHECK(cap_dns_family_limit(capdns, families, 2) == 0); CHECK(runtest(capdns) == - (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6)); + (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6)); cap_close(capdns); @@ -336,7 +446,8 @@ main(void) errno == ENOTCAPABLE); CHECK(runtest(capdns) == - (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET)); + (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET | + GETADDRINFO_AF_INET)); cap_close(capdns); @@ -362,7 +473,8 @@ main(void) errno == ENOTCAPABLE); CHECK(runtest(capdns) == - (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6)); + (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET6)); cap_close(capdns); @@ -472,7 +584,7 @@ main(void) CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && errno == ENOTCAPABLE); - CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET); + CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET | GETADDRINFO_AF_INET)); cap_close(capdns); @@ -508,7 +620,8 @@ main(void) CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && errno == ENOTCAPABLE); - CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6); + CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET6)); cap_close(capdns); @@ -578,7 +691,8 @@ main(void) errno == ENOTCAPABLE); /* Do the limits still hold? */ - CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6); + CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET6)); cap_close(capdns); |