]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
cache: avoid potential out-of-bounds with NSEC3 params
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 15 Jun 2018 09:05:40 +0000 (11:05 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 15 Jun 2018 09:16:13 +0000 (11:16 +0200)
It's possible the parser wouldn't let such RR through,
and it's most likely validator shouldn't let them through.
Even so, I feel better to check anyway.

lib/cache/api.c
lib/cache/impl.h

index 0fa6f577069b2f674f6cef4c306292b95d4de824..1344ebe717fd2819f6100f8410eb482efd4debe7 100644 (file)
@@ -473,7 +473,10 @@ static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry,
 
                assert(rr->type == KNOT_RRTYPE_NSEC3);
                const knot_rdata_t *np_data = knot_rdata_data(rr->rrs.data);
+               const int rdlen = knot_rdata_rdlen(rr->rrs.data);
+               if (rdlen <= 4) return kr_error(EILSEQ); /*< data from outside; less trust */
                const int np_dlen = nsec_p_rdlen(np_data);
+               if (np_dlen > rdlen) return kr_error(EILSEQ);
                key = key_NSEC3(k, encloser, nsec_p_mkHash(np_data));
                if (npp && !*npp) {
                        *npp = mm_alloc(&qry->request->pool, np_dlen);
@@ -606,6 +609,7 @@ static int stash_rrarray_entry(ranked_rr_array_t *arr, int arr_i,
        ssize_t written = stash_rrset(cache, qry, rr, rr_sigs, qry->timestamp.tv_sec,
                                        entry->rank, nsec_pmap, has_optout);
        if (written < 0) {
+               kr_log_error("[%5hu][cach] stash failed, ret = %d\n", qry->id, ret);
                return (int) written;
        }
 
index 74271315e620d6c5eb11cb7d87750eac4beee6d7..d72f74faa18a9dd3c8c1d4b778e5ad8f012c43a3 100644 (file)
@@ -80,7 +80,7 @@ static inline struct entry_h * entry_h_consistent_NSEC(knot_db_val_t data)
 
 static inline int nsec_p_rdlen(const uint8_t *rdata)
 {
-       //TODO: the zero case? // FIXME security: overflow potential
+       //TODO: the zero case?
        return rdata ? 5 + rdata[4] : 0; /* rfc5155 4.2 and 3.2. */
 }
 static const int NSEC_P_MAXLEN = sizeof(uint32_t) + 5 + 255; // TODO: remove??