From a5c6f93fa25cce2fbe689ca4d4949d10dd49d350 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 20 Sep 2009 15:41:24 +0000 Subject: [PATCH] Fix data length in encoding dns queries --- src/dns.c | 73 +++++++++++++++++++++++++---------------------------- tests/dns.c | 6 +++-- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/dns.c b/src/dns.c index a11e130..8f6cae8 100644 --- a/src/dns.c +++ b/src/dns.c @@ -90,47 +90,41 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ putshort(&p, C_IN); putlong(&p, 0); /* TTL */ - if (q->type == T_CNAME || q->type == T_A || q->type == T_MX) - { - /* data is expected to be like "Hblabla.host.name.com\0" */ + if (q->type == T_CNAME || q->type == T_A || q->type == T_MX) { + /* data is expected to be like "Hblabla.host.name.com\0" */ - char *startp = p; - int namelen; + char *startp = p; + int namelen; - p += 2; /* skip 2 bytes length */ - CHECKLEN(2); - if (q->type == T_MX) - putshort(&p, 10); /* preference */ - putname(&p, buflen - (p - buf), data); - CHECKLEN(0); - namelen = p - startp; - namelen -= 2; - putshort(&startp, namelen); - } - else if (q->type == T_TXT) - { - /* TXT has binary or base-X data */ - char *startp = p; - int txtlen; - - p += 2; /* skip 2 bytes length */ - puttxtbin(&p, buflen - (p - buf), data, datalen); - CHECKLEN(0); - txtlen = p - startp; - txtlen -= 2; - putshort(&startp, txtlen); - } - else - { - /* NULL has raw binary data */ - datalen = MIN(datalen, buflen - (p - buf)); - CHECKLEN(2); - putshort(&p, datalen); - CHECKLEN(datalen); - putdata(&p, data, datalen); - CHECKLEN(0); - } + p += 2; /* skip 2 bytes length */ + CHECKLEN(2); + if (q->type == T_MX) + putshort(&p, 10); /* preference */ + putname(&p, buflen - (p - buf), data); + CHECKLEN(0); + namelen = p - startp; + namelen -= 2; + putshort(&startp, namelen); + } else if (q->type == T_TXT) { + /* TXT has binary or base-X data */ + char *startp = p; + int txtlen; + p += 2; /* skip 2 bytes length */ + puttxtbin(&p, buflen - (p - buf), data, datalen); + CHECKLEN(0); + txtlen = p - startp; + txtlen -= 2; + putshort(&startp, txtlen); + } else { + /* NULL has raw binary data */ + datalen = MIN(datalen, buflen - (p - buf)); + CHECKLEN(2); + putshort(&p, datalen); + CHECKLEN(datalen); + putdata(&p, data, datalen); + CHECKLEN(0); + } break; case QR_QUERY: /* Note that iodined also uses this for forward queries */ @@ -138,7 +132,8 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ header->qdcount = htons(1); header->arcount = htons(1); - putname(&p, buflen - (p - buf), data); + datalen = MIN(datalen, buflen - (p - buf)); + putname(&p, datalen, data); CHECKLEN(4); putshort(&p, q->type); diff --git a/tests/dns.c b/tests/dns.c index 55e753b..21745c7 100644 --- a/tests/dns.c +++ b/tests/dns.c @@ -69,8 +69,9 @@ START_TEST(test_encode_query) char *d; size_t len; int ret; + int enclen; - len = sizeof(buf); + enclen = sizeof(resolv); memset(&buf, 0, sizeof(buf)); memset(&resolv, 0, sizeof(resolv)); memset(&q, 0, sizeof(struct query)); @@ -80,12 +81,13 @@ START_TEST(test_encode_query) enc = get_base32_encoder(); *d++ = 'A'; - enc->encode(d, &len, innerData, strlen(innerData)); + enc->encode(d, &enclen, innerData, strlen(innerData)); d = resolv + strlen(resolv); if (*d != '.') { *d++ = '.'; } strcpy(d, topdomain); + len = sizeof(buf); ret = dns_encode(buf, len, &q, QR_QUERY, resolv, strlen(resolv)); len = sizeof(query_packet) - 1; /* Skip extra null character */