summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2012-08-19 16:17:41 +0000
committerEric Faurot <eric@cvs.openbsd.org>2012-08-19 16:17:41 +0000
commitfd61f36b2861343b5f5d10cd950a4e9eb9b51425 (patch)
tree8b8e24578395221b33fc7b5f9a09892f597e52ac /lib
parent0c0c72d3447ee021bcc2674934484c9aa1f2b59a (diff)
When building dynamic hostent and netent, allocate a single linear buffer to
hold both the structure and the data. The freehostent() and freenetent() API functions are not needed anymore. While there, ensure that the constructed addr and alias lists are really NULL terminated.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/asr/asr.h4
-rw-r--r--lib/libc/asr/asr_resolver.c10
-rw-r--r--lib/libc/asr/async_resolver.318
-rw-r--r--lib/libc/asr/gethostnamadr_async.c89
-rw-r--r--lib/libc/asr/getnameinfo_async.c4
-rw-r--r--lib/libc/asr/getnetnamadr_async.c67
6 files changed, 88 insertions, 104 deletions
diff --git a/lib/libc/asr/asr.h b/lib/libc/asr/asr.h
index 2a562092326..66516331328 100644
--- a/lib/libc/asr/asr.h
+++ b/lib/libc/asr/asr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.h,v 1.1 2012/04/14 09:24:18 eric Exp $ */
+/* $OpenBSD: asr.h,v 1.2 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -94,11 +94,9 @@ struct async *getrrsetbyname_async(const char *, unsigned int, unsigned int,
struct async *gethostbyname_async(const char *, struct asr *);
struct async *gethostbyname2_async(const char *, int, struct asr *);
struct async *gethostbyaddr_async(const void *, socklen_t, int, struct asr *);
-void freehostent(struct hostent *);
struct async *getnetbyname_async(const char *, struct asr *);
struct async *getnetbyaddr_async(in_addr_t, int, struct asr *);
-void freenetent(struct netent *);
struct async *getaddrinfo_async(const char *, const char *,
const struct addrinfo *, struct asr *);
diff --git a/lib/libc/asr/asr_resolver.c b/lib/libc/asr/asr_resolver.c
index acebcbd6753..158f2914cfe 100644
--- a/lib/libc/asr/asr_resolver.c
+++ b/lib/libc/asr/asr_resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_resolver.c,v 1.8 2012/08/18 16:48:17 eric Exp $ */
+/* $OpenBSD: asr_resolver.c,v 1.9 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -319,7 +319,7 @@ _gethostbyname(const char *name, int af)
return (NULL);
h = _mkstatichostent(ar.ar_hostent);
- freehostent(ar.ar_hostent);
+ free(ar.ar_hostent);
return (h);
}
@@ -357,7 +357,7 @@ gethostbyaddr(const void *addr, socklen_t len, int af)
return (NULL);
h = _mkstatichostent(ar.ar_hostent);
- freehostent(ar.ar_hostent);
+ free(ar.ar_hostent);
return (h);
}
@@ -438,7 +438,7 @@ getnetbyname(const char *name)
return (NULL);
n = _mkstaticnetent(ar.ar_netent);
- freenetent(ar.ar_netent);
+ free(ar.ar_netent);
return (n);
}
@@ -464,7 +464,7 @@ getnetbyaddr(in_addr_t net, int type)
return (NULL);
n = _mkstaticnetent(ar.ar_netent);
- freenetent(ar.ar_netent);
+ free(ar.ar_netent);
return (n);
}
diff --git a/lib/libc/asr/async_resolver.3 b/lib/libc/asr/async_resolver.3
index 81ae9f92e23..77e03a9c9bb 100644
--- a/lib/libc/asr/async_resolver.3
+++ b/lib/libc/asr/async_resolver.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: async_resolver.3,v 1.3 2012/08/18 16:48:17 eric Exp $
+.\" $OpenBSD: async_resolver.3,v 1.4 2012/08/19 16:17:40 eric Exp $
.\"
.\" Copyright (c) 2012, Eric Faurot <eric@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 18 2012 $
+.Dd $Mdocdate: August 19 2012 $
.Dt ASYN_RESOLVER 3
.Os
.Sh NAME
@@ -30,7 +30,6 @@
.Nm gethostbyname_async ,
.Nm gethostbyname2_async ,
.Nm gethostbyaddr_async ,
-.Nm freehostent ,
.Nm getnetbyname_async ,
.Nm getnetbyaddr_async ,
.Nm freenetent ,
@@ -61,13 +60,10 @@
.Fn gethostbyname2_async "const char *name" "int af" "struct asr *asr"
.Ft struct async*
.Fn gethostbyaddr_async "const void *addr" "socklen_t len" "int af" "struct asr *asr"
-.Ft void
-.Fn freehostent "struct hostent *h"
+.Ft struct async*
.Fn getnetbyname_async "const char *name" "struct asr *asr"
.Ft struct async*
.Fn getnetbyaddr_async "in_addr_t net" "int type" "struct asr *asr"
-.Ft void
-.Fn freenetent "struct netent *n"
.Ft struct async*
.Fn getaddrinfo_async "const char *hostname" "const char *servname" "const struct addrinfo *hints" "struct asr *asr"
.Ft struct async*
@@ -308,10 +304,8 @@ in the
.Ar ar_hostent
field.
Note that unlike their blocking counterparts, these functions always return a
-pointer to newly allocated memory.
-Therefore, the pointer must be freed through the new
-.Fn freehostent
-call.
+pointer to newly allocated memory, which must be released by the caller using
+.Xr free 3 .
.Pp
Similarly, the
.Fn getnetbyname_async
@@ -325,7 +319,7 @@ in the
.Ar ar_netent
field.
The memory there is also allocated for the request, and it must be freed by
-.Fn freenetent .
+.Xr free 3 .
.Pp
The
.Fn getaddrinfo_async
diff --git a/lib/libc/asr/gethostnamadr_async.c b/lib/libc/asr/gethostnamadr_async.c
index 47fecca10da..bc338d71776 100644
--- a/lib/libc/asr/gethostnamadr_async.c
+++ b/lib/libc/asr/gethostnamadr_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gethostnamadr_async.c,v 1.5 2012/07/12 13:03:34 eric Exp $ */
+/* $OpenBSD: gethostnamadr_async.c,v 1.6 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -34,6 +34,11 @@
#define MAXALIASES 16
#define MAXADDRS 16
+#define HOSTENT_PTR(h) ((char**)(((char*)h) + sizeof (*h)))
+#define HOSTENT_POS(h) HOSTENT_PTR(h)[0]
+#define HOSTENT_STOP(h) HOSTENT_PTR(h)[1]
+#define HOSTENT_LEFT(h) (HOSTENT_STOP(h) - HOSTENT_POS(h))
+
ssize_t addr_as_fqdn(const char *, int, char *, size_t);
static int gethostnamadr_async_run(struct async *, struct async_res *);
@@ -291,7 +296,7 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
if (hostent_add_addr(ar->ar_hostent,
as->as.hostnamadr.addr,
as->as.hostnamadr.addrlen) == -1) {
- freehostent(ar->ar_hostent);
+ free(ar->ar_hostent);
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
async_set_state(as, ASR_STATE_HALT);
@@ -305,7 +310,7 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
*/
if (as->as_type == ASR_GETHOSTBYNAME &&
ar->ar_hostent->h_addr_list[0] == NULL) {
- freehostent(ar->ar_hostent);
+ free(ar->ar_hostent);
async_set_state(as, ASR_STATE_NEXT_DB);
break;
}
@@ -381,7 +386,7 @@ found:
goto fail;
return (h);
fail:
- freehostent(h);
+ free(h);
return (NULL);
}
@@ -454,7 +459,7 @@ hostent_from_packet(int reqtype, int family, char *pkt, size_t pktlen)
return (h);
fail:
- freehostent(h);
+ free(h);
return (NULL);
}
@@ -462,19 +467,19 @@ static struct hostent *
hostent_alloc(int family)
{
struct hostent *h;
+ size_t alloc;
- h = calloc(1, sizeof *h);
- if (h == NULL)
+ alloc = sizeof(*h) + (2 + MAXALIASES + MAXADDRS) * sizeof(char*) + 1024;
+ if ((h = calloc(1, alloc)) == NULL)
return (NULL);
- h->h_aliases = calloc(MAXALIASES, sizeof *h->h_aliases);
- h->h_addr_list = calloc(MAXADDRS, sizeof *h->h_addr_list);
- if (h->h_aliases == NULL || h->h_addr_list == NULL) {
- freehostent(h);
- return (NULL);
- }
h->h_addrtype = family;
h->h_length = (family == AF_INET) ? 4 : 16;
+ h->h_aliases = HOSTENT_PTR(h) + 2;
+ h->h_addr_list = h->h_aliases + MAXALIASES;
+
+ HOSTENT_STOP(h) = (char*)(h) + alloc;
+ HOSTENT_POS(h) = (char*)(h->h_addr_list + MAXADDRS);
return (h);
}
@@ -490,12 +495,14 @@ hostent_set_cname(struct hostent *h, const char *name, int isdname)
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf) - 1] = '\0';
- h->h_name = strdup(buf);
- } else {
- h->h_name = strdup(name);
+ name = buf;
}
- if (h->h_name == NULL)
- return (-1);
+ if (strlen(name) + 1 >= HOSTENT_LEFT(h))
+ return (1);
+
+ strlcpy(HOSTENT_POS(h), name, HOSTENT_LEFT(h));
+ h->h_name = HOSTENT_POS(h);
+ HOSTENT_POS(h) += strlen(name) + 1;
return (0);
}
@@ -506,21 +513,23 @@ hostent_add_alias(struct hostent *h, const char *name, int isdname)
char buf[MAXDNAME];
size_t i;
- for (i = 0; i < MAXALIASES; i++)
+ for (i = 0; i < MAXALIASES - 1; i++)
if (h->h_aliases[i] == NULL)
break;
- if (i == MAXALIASES)
+ if (i == MAXALIASES - 1)
return (0);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf)-1] = '\0';
- h->h_aliases[i] = strdup(buf);
- } else {
- h->h_aliases[i] = strdup(name);
+ name = buf;
}
- if (h->h_aliases[i] == NULL)
- return (-1);
+ if (strlen(name) + 1 >= HOSTENT_LEFT(h))
+ return (1);
+
+ strlcpy(HOSTENT_POS(h), name, HOSTENT_LEFT(h));
+ h->h_aliases[i] = HOSTENT_POS(h);
+ HOSTENT_POS(h) += strlen(name) + 1;
return (0);
}
@@ -530,36 +539,22 @@ hostent_add_addr(struct hostent *h, const void *addr, int size)
{
int i;
- for (i = 0; i < MAXADDRS; i++)
+ for (i = 0; i < MAXADDRS - 1; i++)
if (h->h_addr_list[i] == NULL)
break;
- if (i == MAXADDRS)
+ if (i == MAXADDRS - 1)
return (0);
- h->h_addr_list[i] = malloc(size);
- if (h->h_addr_list[i] == NULL)
- return (-1);
- memmove(h->h_addr_list[i], addr, size);
+ if (size >= HOSTENT_LEFT(h))
+ return (1);
- return (0);
-}
+ memmove(HOSTENT_POS(h), addr, size);
+ h->h_addr_list[i] = HOSTENT_POS(h);
+ HOSTENT_POS(h) += size;
-void
-freehostent(struct hostent *h)
-{
- char **c;
-
- free(h->h_name);
- for (c = h->h_aliases; *c; c++)
- free(*c);
- free(h->h_aliases);
- for (c = h->h_addr_list; *c; c++)
- free(*c);
- free(h->h_addr_list);
- free(h);
+ return (0);
}
-
ssize_t
addr_as_fqdn(const char *addr, int family, char *dst, size_t max)
{
diff --git a/lib/libc/asr/getnameinfo_async.c b/lib/libc/asr/getnameinfo_async.c
index e32501f8337..4b251801896 100644
--- a/lib/libc/asr/getnameinfo_async.c
+++ b/lib/libc/asr/getnameinfo_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnameinfo_async.c,v 1.3 2012/08/18 11:19:51 eric Exp $ */
+/* $OpenBSD: getnameinfo_async.c,v 1.4 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -180,7 +180,7 @@ getnameinfo_async_run(struct async *as, struct async_res *ar)
ar->ar_gai_errno = EAI_OVERFLOW;
else
ar->ar_gai_errno = 0;
- freehostent(ar->ar_hostent);
+ free(ar->ar_hostent);
}
async_set_state(as, ASR_STATE_HALT);
diff --git a/lib/libc/asr/getnetnamadr_async.c b/lib/libc/asr/getnetnamadr_async.c
index 70efc2962f2..bc03a643166 100644
--- a/lib/libc/asr/getnetnamadr_async.c
+++ b/lib/libc/asr/getnetnamadr_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnetnamadr_async.c,v 1.2 2012/07/10 17:30:38 eric Exp $ */
+/* $OpenBSD: getnetnamadr_async.c,v 1.3 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -32,6 +32,11 @@
#define MAXALIASES 16
+#define NETENT_PTR(n) ((char**)(((char*)n) + sizeof (*n)))
+#define NETENT_POS(n) NETENT_PTR(n)[0]
+#define NETENT_STOP(n) NETENT_PTR(n)[1]
+#define NETENT_LEFT(n) (NETENT_STOP(n) - NETENT_POS(n))
+
ssize_t addr_as_fqdn(const char *, int, char *, size_t);
static int getnetnamadr_async_run(struct async *, struct async_res *);
@@ -229,7 +234,7 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar)
if (as->as_type == ASR_GETNETBYNAME &&
ar->ar_netent->n_net == 0) {
/* XXX wrong */
- freenetent(ar->ar_netent);
+ free(ar->ar_netent);
async_set_state(as, ASR_STATE_NEXT_DB);
} else {
ar->ar_h_errno = NETDB_SUCCESS;
@@ -303,7 +308,7 @@ found:
e->n_net = inet_network(tokens[1]);
return (e);
fail:
- freenetent(e);
+ free(e);
return (NULL);
}
@@ -358,7 +363,7 @@ netent_from_packet(int reqtype, char *pkt, size_t pktlen)
return (n);
fail:
- freenetent(n);
+ free(n);
return (NULL);
}
@@ -366,17 +371,17 @@ static struct netent *
netent_alloc(int family)
{
struct netent *n;
+ size_t alloc;
- n = calloc(1, sizeof *n);
- if (n == NULL)
+ alloc = sizeof(*n) + (2 + MAXALIASES) * sizeof(char*) + 1024;
+ if ((n = calloc(1, alloc)) == NULL)
return (NULL);
- n->n_aliases = calloc(MAXALIASES, sizeof *n->n_aliases);
- if (n->n_aliases == NULL) {
- freenetent(n);
- return (NULL);
- }
n->n_addrtype = family;
+ n->n_aliases = NETENT_PTR(n) + 2;
+
+ NETENT_STOP(n) = (char*)(n) + alloc;
+ NETENT_POS(n) = (char *)(n->n_aliases + MAXALIASES);
return (n);
}
@@ -392,12 +397,14 @@ netent_set_cname(struct netent *n, const char *name, int isdname)
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf) - 1] = '\0';
- n->n_name = strdup(buf);
- } else {
- n->n_name = strdup(name);
+ name = buf;
}
- if (n->n_name == NULL)
- return (-1);
+ if (strlen(name) + 1 >= NETENT_LEFT(n))
+ return (1);
+
+ strlcpy(NETENT_POS(n), name, NETENT_LEFT(n));
+ n->n_name = NETENT_POS(n);
+ NETENT_POS(n) += strlen(name) + 1;
return (0);
}
@@ -408,33 +415,23 @@ netent_add_alias(struct netent *n, const char *name, int isdname)
char buf[MAXDNAME];
size_t i;
- for (i = 0; i < MAXALIASES; i++)
+ for (i = 0; i < MAXALIASES - 1; i++)
if (n->n_aliases[i] == NULL)
break;
- if (i == MAXALIASES)
+ if (i == MAXALIASES - 1)
return (0);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf)-1] = '\0';
- n->n_aliases[i] = strdup(buf);
- } else {
- n->n_aliases[i] = strdup(name);
+ name = buf;
}
- if (n->n_aliases[i] == NULL)
- return (-1);
+ if (strlen(name) + 1 >= NETENT_LEFT(n))
+ return (1);
- return (0);
-}
-
-void
-freenetent(struct netent *n)
-{
- char **c;
+ strlcpy(NETENT_POS(n), name, NETENT_LEFT(n));
+ n->n_aliases[i] = NETENT_POS(n);
+ NETENT_POS(n) += strlen(name) + 1;
- free(n->n_name);
- for (c = n->n_aliases; *c; c++)
- free(*c);
- free(n->n_aliases);
- free(n);
+ return (0);
}