From: Marek VavruĊĦa Date: Wed, 25 Jul 2018 18:43:19 +0000 (-0600) Subject: layer/iterate: fix cache injection via CNAME X-Git-Tag: v2.4.1~3^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2dd680d54c1753c1ad1f973be733d879cea1a73;p=thirdparty%2Fknot-resolver.git layer/iterate: fix cache injection via CNAME The current default mode doesn't check bailiwick anymore when unrolling CNAME chains, so if an answer contains: ``` testingme.com. 3600 IN CNAME victim.com. victim.com. 172800 IN NS attackers.ns ``` The resolver will cache both records as authoritative even though `victim.com` isn't in the current bailiwick. This was previously checked in 79d9931daaa5b9e6c7965f6ee29c965786a4754e, but removed in refactoring. --- diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index b30d451b3..a02acfba7 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -500,7 +500,8 @@ static int unroll_cname(knot_pkt_t *pkt, struct kr_request *req, bool referral, || type == KNOT_RRTYPE_CNAME || type == KNOT_RRTYPE_DNAME; /* TODO: actually handle DNAMEs */ if (rr->rclass != KNOT_CLASS_IN || !type_OK - || !knot_dname_is_equal(rr->owner, cname)) { + || !knot_dname_is_equal(rr->owner, cname) + || !knot_dname_in(query->zone_cut.name, rr->owner)) { continue; } @@ -565,7 +566,14 @@ static int unroll_cname(knot_pkt_t *pkt, struct kr_request *req, bool referral, cname = pending_cname; break; } - /* try to unroll cname only within current zone */ + /* Information outside bailiwick is not trusted. */ + if (!knot_dname_in(query->zone_cut.name, pending_cname)) { + cname = pending_cname; + break; + } + /* The validator still can't handle multiple zones in one answer, + * so we only follow if a single label is replaced. + * TODO: this still isn't 100%, as the target may have a NS+DS. */ const int pending_labels = knot_dname_labels(pending_cname, NULL); if (pending_labels != cname_labels) { cname = pending_cname;