Commit Diff
Diff:
6773e0798c6c3769be501cf6fe161a45fb40c9f8
fd0a16b593a6401d1255527026fb379052f7a416
Commit:
fd0a16b593a6401d1255527026fb379052f7a416
Tree:
c3471417fd9b472bee63226b3da84f6a92ab5969
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Sat Jun 20 17:04:09 2015 UTC
Message:
* catch truncation
blob - 61907435adb026f54135a3a52ff2e48cdaad90fe
blob + 390de635e33d20a59b85bc1095e3add1a94c11e4
--- additional.c
+++ additional.c
@@ -41,7 +41,7 @@ extern void * find_substruct(struct domain *, u_int16
extern int dnssec;
-static const char rcsid[] = "$Id: additional.c,v 1.5 2015/06/20 15:58:41 pjp Exp $";
+static const char rcsid[] = "$Id: additional.c,v 1.6 2015/06/20 17:04:09 pjp Exp $";
/*
@@ -526,8 +526,9 @@ additional_rrsig(char *name, int namelen, int inttype,
rroffset = offset;
+ /* check if we go over our return length */
if ((offset + namelen) > replylen)
- goto out;
+ return 0;
memcpy(&reply[offset], name, namelen);
offset += namelen;
@@ -538,8 +539,7 @@ additional_rrsig(char *name, int namelen, int inttype,
}
if ((offset + sizeof(struct answer)) > replylen) {
- offset = rroffset;
- goto out;
+ return 0;
}
@@ -558,6 +558,9 @@ additional_rrsig(char *name, int namelen, int inttype,
offset += sizeof(*answer);
rroffset = offset;
+ if ((offset + sdrr->rrsig[inttype].signame_len) > replylen)
+ return 0;
+
memcpy(&reply[offset], &sdrr->rrsig[inttype].signers_name, sdrr->rrsig[inttype].signame_len);
offset += sdrr->rrsig[inttype].signame_len;
@@ -568,6 +571,9 @@ additional_rrsig(char *name, int namelen, int inttype,
offset = tmplen;
}
#endif
+
+ if ((offset + sdrr->rrsig[inttype].signature_len) > replylen)
+ return 0;
memcpy(&reply[offset], &sdrr->rrsig[inttype].signature, sdrr->rrsig[inttype].signature_len);
offset += sdrr->rrsig[inttype].signature_len;
blob - 71555f0e06189ca75c239b8e7d67aa849cb2b9b4
blob + 0753cb35261670f6fd8ebc929fbc0d8b53fb5a89
--- reply.c
+++ reply.c
@@ -91,7 +91,7 @@ struct collects {
extern int debug, verbose, dnssec;
-static const char rcsid[] = "$Id: reply.c,v 1.8 2015/06/20 15:58:41 pjp Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.9 2015/06/20 17:04:09 pjp Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -103,7 +103,7 @@ reply_a(struct sreply *sreply, DB *db)
{
char *reply = sreply->replybuf;
struct dns_header *odh;
- u_int16_t outlen;
+ u_int16_t outlen = 0;
int a_count;
int mod, pos;
@@ -212,8 +212,19 @@ reply_a(struct sreply *sreply, DB *db)
/* Add RRSIG */
if (dnssec && q->dnssecok) {
+ int tmplen = 0;
+
odh->answer = htons(a_count + 1);
- outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_A, sd, reply, replysize, outlen);
+ tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_A, sd, reply, replysize, outlen);
+
+ if (tmplen == 0) {
+ NTOHS(odh->query);
+ SET_DNS_TRUNCATION(odh);
+ HTONS(odh->query);
+ goto out;
+ }
+
+ outlen = tmplen;
}
if (q->edns0len) {
@@ -271,7 +282,7 @@ reply_aaaa(struct sreply *sreply, DB *db)
{
char *reply = sreply->replybuf;
struct dns_header *odh;
- u_int16_t outlen;
+ u_int16_t outlen = 0;
int aaaa_count;
int mod, pos;
@@ -428,7 +439,7 @@ reply_mx(struct sreply *sreply, DB *db)
int mx_count;
u_int16_t *plen;
char *name;
- u_int16_t outlen;
+ u_int16_t outlen = 0;
u_int16_t namelen;
int additional = 0;
@@ -646,12 +657,12 @@ reply_ns(struct sreply *sreply, DB *db)
char *reply = sreply->replybuf;
struct dns_header *odh;
struct domain *sd0;
- int tmplen;
+ int tmplen = 0;
int ns_count;
int mod, pos;
u_int16_t *plen;
char *name;
- u_int16_t outlen;
+ u_int16_t outlen = 0;
u_int16_t namelen;
int additional = 0;
@@ -825,14 +836,23 @@ reply_ns(struct sreply *sreply, DB *db)
else if (odh->nsrr)
odh->nsrr = htons(ns_count + 1);
- outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_NS, sd, reply, replysize, outlen);
+ tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_NS, sd, reply, replysize, outlen);
+
+ if (tmplen == 0) {
+ NTOHS(odh->query);
+ SET_DNS_TRUNCATION(odh);
+ HTONS(odh->query);
+ goto out;
+ }
+
+ outlen = tmplen;
}
/* shuffle through our linked collect structure and add additional */
SLIST_FOREACH(cnp, &collectshead, collect_entry) {
- int addcount = 0;
int tmplen = 0;
+ int addcount = 0;
switch (cnp->type) {
case DNS_TYPE_A:
@@ -850,36 +870,45 @@ reply_ns(struct sreply *sreply, DB *db)
break;
}
- if (tmplen > 0) {
+ if (tmplen > 0)
outlen = tmplen;
- }
+
}
/* Add RRSIG */
if (dnssec && q->dnssecok) {
if (sdhave_a) {
- outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_A, sdhave_a, reply, replysize, outlen);
+ tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_A, sdhave_a, reply, replysize, outlen);
additional++;
+
+ if (tmplen == 0) {
+ NTOHS(odh->query);
+ SET_DNS_TRUNCATION(odh);
+ HTONS(odh->query);
+ goto out;
+ }
+
+ outlen = tmplen;
}
if (sdhave_aaaa) {
- outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_AAAA, sdhave_aaaa, reply, replysize, outlen);
+ tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_AAAA, sdhave_aaaa, reply, replysize, outlen);
additional++;
-
+
+ if (tmplen == 0) {
+ NTOHS(odh->query);
+ SET_DNS_TRUNCATION(odh);
+ HTONS(odh->query);
+ goto out;
+ }
+
+ outlen = tmplen;
}
}
odh->additional = htons(additional);
- while (!SLIST_EMPTY(&collectshead)) {
- cn1 = SLIST_FIRST(&collectshead);
- SLIST_REMOVE_HEAD(&collectshead, collect_entry);
- free(cn1->name);
- free(cn1->sd);
- free(cn1);
- }
-
if (q->edns0len) {
/* tag on edns0 opt record */
NTOHS(odh->additional);
@@ -890,6 +919,14 @@ reply_ns(struct sreply *sreply, DB *db)
}
out:
+ while (!SLIST_EMPTY(&collectshead)) {
+ cn1 = SLIST_FIRST(&collectshead);
+ SLIST_REMOVE_HEAD(&collectshead, collect_entry);
+ free(cn1->name);
+ free(cn1->sd);
+ free(cn1);
+ }
+
if (sreply->sr != NULL) {
retlen = reply_raw2(so, reply, outlen, sreply->sr);
} else {
repomaster@centroid.eu