diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2012-08-19 16:17:41 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2012-08-19 16:17:41 +0000 |
commit | fd61f36b2861343b5f5d10cd950a4e9eb9b51425 (patch) | |
tree | 8b8e24578395221b33fc7b5f9a09892f597e52ac /lib/libc | |
parent | 0c0c72d3447ee021bcc2674934484c9aa1f2b59a (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/libc')
-rw-r--r-- | lib/libc/asr/asr.h | 4 | ||||
-rw-r--r-- | lib/libc/asr/asr_resolver.c | 10 | ||||
-rw-r--r-- | lib/libc/asr/async_resolver.3 | 18 | ||||
-rw-r--r-- | lib/libc/asr/gethostnamadr_async.c | 89 | ||||
-rw-r--r-- | lib/libc/asr/getnameinfo_async.c | 4 | ||||
-rw-r--r-- | lib/libc/asr/getnetnamadr_async.c | 67 |
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); } |