From 2800e375a79db9d35ffeaaa2e6e612c4345475f2 Mon Sep 17 00:00:00 2001
From: Marek Vavrusa <marek@vavrusa.com>
Date: Tue, 19 Jan 2016 12:27:23 -0800
Subject: [PATCH] lib/iterate: ignore out-of-bailiwick NSs for positive answers

there are broken resolution chains where a zone cut is advertised,
but it doesn't exist and the final NS answers from its parent's
zone cut, which is an attempt to escape bailiwick

example:

resolving A ab.cd.ef
NS ef responds:
 - ab.cd.ef NS X ; adverises ab.cd.ef zone cut
X responds:
 - A ab.cd.ef A 1.2.3.4
 - cd.ef NS X ; escapes previously advertised cut

on the other hand, it is important to fail early for referrals as
it signifies a lame answer
---
 lib/layer/iterate.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c
index 32485306f..776691f7c 100644
--- a/lib/layer/iterate.c
+++ b/lib/layer/iterate.c
@@ -223,8 +223,17 @@ static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr, struct kr_request
 	/* Authority MUST be at/below the authority of the nameserver, otherwise
 	 * possible cache injection attempt. */
 	if (!knot_dname_in(cut->name, rr->owner)) {
-		DEBUG_MSG("<= authority: ns outside bailiwick, failing\n");
+		DEBUG_MSG("<= authority: ns outside bailiwick\n");
+#ifdef STRICT_MODE
 		return KNOT_STATE_FAIL;
+#else
+		/* Workaround: ignore out-of-bailiwick NSs for authoritative answers,
+		 * but fail for referrals. This is important to detect lame answers. */
+		if (knot_pkt_section(pkt, KNOT_ANSWER)->count == 0) {
+			state = KNOT_STATE_FAIL;
+		}
+		return state;
+#endif
 	}
 
 	/* Update zone cut name */
-- 
GitLab