diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2013-04-01 20:22:28 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2013-04-01 20:22:28 +0000 |
commit | 998ad194f268d0f8458e936c331db9d2a8ad7218 (patch) | |
tree | 562d0bc74e6f562acf29a4cc642293fcbb1fe62f /lib | |
parent | 030f1f7692150b473bd81cc1ad5311920bec0b2a (diff) |
properly check for domain name truncation at various places and fail
if that happens.
prodded by deraadt@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/asr/asr.c | 30 | ||||
-rw-r--r-- | lib/libc/asr/res_mkquery.c | 16 | ||||
-rw-r--r-- | lib/libc/asr/res_search_async.c | 4 |
3 files changed, 30 insertions, 20 deletions
diff --git a/lib/libc/asr/asr.c b/lib/libc/asr/asr.c index b9c3dc1fbed..6a98f17c4ef 100644 --- a/lib/libc/asr/asr.c +++ b/lib/libc/asr/asr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asr.c,v 1.19 2013/04/01 15:49:54 deraadt Exp $ */ +/* $OpenBSD: asr.c,v 1.20 2013/04/01 20:22:27 eric Exp $ */ /* * Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org> * @@ -465,15 +465,18 @@ asr_make_fqdn(const char *name, const char *domain, char *buf, size_t buflen) len = strlen(name); if (len == 0) { - strlcpy(buf, domain, buflen); + if (strlcpy(buf, domain, buflen) >= buflen) + return (0); } else if (name[len - 1] != '.') { if (domain[0] == '.') domain += 1; - strlcpy(buf, name, buflen); - strlcat(buf, ".", buflen); - strlcat(buf, domain, buflen); + if (strlcpy(buf, name, buflen) >= buflen || + strlcat(buf, ".", buflen) >= buflen || + strlcat(buf, domain, buflen) >= buflen) + return (0); } else { - strlcpy(buf, name, buflen); + if (strlcpy(buf, name, buflen) >= buflen) + return (0); } return (strlen(buf)); @@ -481,6 +484,7 @@ asr_make_fqdn(const char *name, const char *domain, char *buf, size_t buflen) /* * Concatenate a name and a domain name. The result has no trailing dot. + * Return the resulting string length, or 0 in case of error. */ size_t asr_domcat(const char *name, const char *domain, char *buf, size_t buflen) @@ -963,8 +967,8 @@ enum { * multiple times (with the same name) to generate the next possible domain * name, if any. * - * It returns 0 if it could generate a new domain name, or -1 when all - * possibilites have been exhausted. + * It returns -1 if all possibilities have been exhausted, 0 if there was an + * error generating the next name, or the resulting name length. */ int asr_iter_domain(struct async *as, const char *name, char * buf, size_t len) @@ -1018,8 +1022,9 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len) if ((asr_ndots(name)) >= as->as_ctx->ac_ndots) { DPRINT("asr: asr_iter_domain(\"%s\") ndots\n", name); as->as_dom_flags |= ASYNC_DOM_NDOTS; - strlcpy(buf, name, len); - return (0); + if (strlcpy(buf, name, len) >= len) + return (0); + return (strlen(buf)); } /* Otherwise, starts using the search domains */ /* FALLTHROUGH */ @@ -1044,8 +1049,9 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len) if (!(as->as_dom_flags & ASYNC_DOM_NDOTS)) { DPRINT("asr: asr_iter_domain(\"%s\") as is\n", name); as->as_dom_flags |= ASYNC_DOM_ASIS; - strlcpy(buf, name, len); - return (0); + if (strlcpy(buf, name, len) >= len) + return (0); + return (strlen(buf)); } /* Otherwise, we are done. */ diff --git a/lib/libc/asr/res_mkquery.c b/lib/libc/asr/res_mkquery.c index f5479d5c00c..ffd7a34a411 100644 --- a/lib/libc/asr/res_mkquery.c +++ b/lib/libc/asr/res_mkquery.c @@ -1,4 +1,4 @@ -/* $OpenBSD: res_mkquery.c,v 1.4 2013/03/29 22:51:35 guenther Exp $ */ +/* $OpenBSD: res_mkquery.c,v 1.5 2013/04/01 20:22:27 eric Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> * @@ -43,8 +43,8 @@ res_mkquery(int op, const char *dname, int class, int type, return (-1); if (dname[0] == '\0' || dname[strlen(dname) - 1] != '.') { - strlcpy(fqdn, dname, sizeof fqdn); - if (strlcat(fqdn, ".", sizeof fqdn) >= sizeof fqdn) + if (strlcpy(fqdn, dname, sizeof(fqdn)) >= sizeof(fqdn) || + strlcat(fqdn, ".", sizeof(fqdn)) >= sizeof(fqdn)) return (-1); dname = fqdn; } @@ -89,13 +89,17 @@ res_querydomain(const char *name, /* we really want domain to end with a dot for now */ if (domain && ((n = strlen(domain)) == 0 || domain[n - 1 ] != '.')) { - strlcpy(ndom, domain, sizeof ndom); - strlcat(ndom, ".", sizeof ndom); + if (strlcpy(ndom, domain, sizeof(ndom)) >= sizeof(ndom) || + strlcat(ndom, ".", sizeof(ndom)) >= sizeof(ndom)) { + h_errno = NETDB_INTERNAL; + errno = EINVAL; + return (-1); + } domain = ndom; } if (asr_make_fqdn(name, domain, fqdn, sizeof fqdn) == 0) { - h_errno = NO_RECOVERY; + h_errno = NETDB_INTERNAL; errno = EINVAL; return (-1); } diff --git a/lib/libc/asr/res_search_async.c b/lib/libc/asr/res_search_async.c index a00defc5ac5..fae802f5e93 100644 --- a/lib/libc/asr/res_search_async.c +++ b/lib/libc/asr/res_search_async.c @@ -1,4 +1,4 @@ -/* $OpenBSD: res_search_async.c,v 1.5 2013/04/01 15:49:54 deraadt Exp $ */ +/* $OpenBSD: res_search_async.c,v 1.6 2013/04/01 20:22:27 eric Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> * @@ -121,7 +121,7 @@ res_search_async_run(struct async *as, struct async_res *ar) async_set_state(as, ASR_STATE_NOT_FOUND); break; } - if (r > sizeof(fqdn)) { + if (r == 0) { ar->ar_errno = EINVAL; ar->ar_h_errno = NO_RECOVERY; ar->ar_datalen = -1; |