]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
validate: additional bailiwick checks
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 31 Jul 2018 14:28:55 +0000 (16:28 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Thu, 2 Aug 2018 09:54:55 +0000 (09:54 +0000)
Let's use this as another layer of defense against our internal bugs.

lib/layer/validate.c

index 99d28c8dfb13bcce146ebb501e1610b579ebfaa3..11237cc8b381b7fae25bf95b5f981e6587f46bc0 100644 (file)
@@ -775,8 +775,12 @@ static int check_signer(kr_layer_t *ctx, knot_pkt_t *pkt)
 }
 
 /** Change ranks of RRs from this single iteration:
- * _INITIAL or _TRY or _MISSING -> rank_to_set. */
-static void rank_records(kr_layer_t *ctx, enum kr_rank rank_to_set)
+ * _INITIAL or _TRY or _MISSING -> rank_to_set.
+ *
+ * Optionally do this only in a `bailiwick` (if not NULL).
+ * Iterator shouldn't have selected such records, but we check to be sure. */
+static void rank_records(kr_layer_t *ctx, enum kr_rank rank_to_set,
+                        const knot_dname_t *bailiwick)
 {
        struct kr_request *req     = ctx->req;
        struct kr_query *qry       = req->current_query;
@@ -788,6 +792,9 @@ static void rank_records(kr_layer_t *ctx, enum kr_rank rank_to_set)
                        if (entry->qry_uid != qry->uid) {
                                continue;
                        }
+                       if (bailiwick && !knot_dname_in(bailiwick, entry->rr->owner)) {
+                               continue;
+                       }
                        if (kr_rank_test(entry->rank, KR_RANK_INITIAL)
                            || kr_rank_test(entry->rank, KR_RANK_TRY)
                            || kr_rank_test(entry->rank, KR_RANK_MISSING)) {
@@ -863,7 +870,7 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
        /* Pass-through if user doesn't want secure answer or stub. */
        /* @todo: Validating stub resolver mode. */
        if (qry->flags.STUB) {
-               rank_records(ctx, KR_RANK_OMIT);
+               rank_records(ctx, KR_RANK_OMIT, NULL);
                return ctx->state;
        }
        uint8_t pkt_rcode = knot_wire_get_rcode(pkt->wire);
@@ -884,7 +891,7 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
        if (!(qry->flags.DNSSEC_WANT)) {
                const bool is_insec = qry->flags.CACHED && qry->flags.DNSSEC_INSECURE;
                if ((qry->flags.DNSSEC_INSECURE)) {
-                       rank_records(ctx, KR_RANK_INSECURE);
+                       rank_records(ctx, KR_RANK_INSECURE, qry->zone_cut.name);
                }
                if (is_insec && qry->parent != NULL) {
                        /* We have got insecure answer from cache.
@@ -906,7 +913,7 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
        if (knot_wire_get_cd(req->answer->wire)) {
                check_wildcard(ctx);
                wildcard_adjust_to_wire(req, qry);
-               rank_records(ctx, KR_RANK_OMIT);
+               rank_records(ctx, KR_RANK_OMIT, NULL);
                return ctx->state;
        }
        /* Answer for RRSIG may not set DO=1, but all records MUST still validate. */
@@ -954,7 +961,7 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
                        /* ^ the message is a bit imprecise to avoid being too verbose */
                        qry->flags.DNSSEC_WANT = false;
                        qry->flags.DNSSEC_INSECURE = true;
-                       rank_records(ctx, KR_RANK_INSECURE);
+                       rank_records(ctx, KR_RANK_INSECURE, qry->zone_cut.name);
                        mark_insecure_parents(qry);
                        return KR_STATE_DONE;
                } else if (ret != 0) {