diff options
author | Szabolcs Nagy <nsz@port70.net> | 2014-06-06 19:20:07 +0200 |
---|---|---|
committer | Szabolcs Nagy <nsz@port70.net> | 2014-06-06 20:41:15 +0200 |
commit | 07355f503a9b0a3ab7a051e2931499a4c5898b15 (patch) | |
tree | 2807935cfeca2b4bc8335352d7b134fa5b58f0e7 | |
parent | 9ce2860fa34ede8f84b8ca5ac1746a58b171a023 (diff) | |
download | musl-07355f503a9b0a3ab7a051e2931499a4c5898b15.tar.gz musl-07355f503a9b0a3ab7a051e2931499a4c5898b15.tar.xz musl-07355f503a9b0a3ab7a051e2931499a4c5898b15.zip |
accept trailing . and empty domain names
trailing . should be accepted in domain name strings by convention (RFC 1034), host name lookup accepts "." but rejects empty "", res_* interfaces also accept empty name following existing practice.
-rw-r--r-- | src/network/lookup_name.c | 7 | ||||
-rw-r--r-- | src/network/res_mkquery.c | 13 | ||||
-rw-r--r-- | src/network/res_querydomain.c | 8 |
3 files changed, 16 insertions, 12 deletions
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c index 68b172b4..743aa082 100644 --- a/src/network/lookup_name.c +++ b/src/network/lookup_name.c @@ -14,7 +14,7 @@ static int is_valid_hostname(const char *host) { const unsigned char *s; - if (strnlen(host, 254)-1 >= 253 || mbstowcs(0, host, 0) == -1) return 0; + if (strnlen(host, 255)-1 >= 254 || mbstowcs(0, host, 0) == -1) return 0; for (s=(void *)host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++); return !*s; } @@ -152,8 +152,9 @@ int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], c *canon = 0; if (name) { - size_t l; - if ((l = strnlen(name, 254))-1 >= 253) + /* reject empty name and check len so it fits into temp bufs */ + size_t l = strnlen(name, 255); + if (l-1 >= 254) return EAI_NONAME; memcpy(canon, name, l+1); } diff --git a/src/network/res_mkquery.c b/src/network/res_mkquery.c index 7c49709e..ec4568ac 100644 --- a/src/network/res_mkquery.c +++ b/src/network/res_mkquery.c @@ -10,13 +10,16 @@ int __res_mkquery(int op, const char *dname, int class, int type, int id, i, j; unsigned char q[280]; struct timespec ts; - size_t l = strnlen(dname, 254); + size_t l = strnlen(dname, 255); + int n; - if (l-1>=253 || buflen<18+l || op>15u || class>255u || type>255u) + if (l && dname[l-1]=='.') l--; + n = 17+l+!!l; + if (l>253 || buflen<n || op>15u || class>255u || type>255u) return -1; /* Construct query template - ID will be filled later */ - memset(q, 0, 18+l); + memset(q, 0, n); q[2] = op*8 + 1; q[5] = 1; memcpy((char *)q+13, dname, l); @@ -34,8 +37,8 @@ int __res_mkquery(int op, const char *dname, int class, int type, q[0] = id/256; q[1] = id; - memcpy(buf, q, 18+l); - return 18+l; + memcpy(buf, q, n); + return n; } weak_alias(__res_mkquery, res_mkquery); diff --git a/src/network/res_querydomain.c b/src/network/res_querydomain.c index 8ba31f45..727e6f6b 100644 --- a/src/network/res_querydomain.c +++ b/src/network/res_querydomain.c @@ -3,10 +3,10 @@ int res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *dest, int len) { - char tmp[254]; - size_t nl = strnlen(name, 254); - size_t dl = strnlen(domain, 254); - if (nl+dl+1 > 253) return -1; + char tmp[255]; + size_t nl = strnlen(name, 255); + size_t dl = strnlen(domain, 255); + if (nl+dl+1 > 254) return -1; memcpy(tmp, name, nl); tmp[nl] = '.'; memcpy(tmp+nl+1, domain, dl+1); |