From 06fb30d0a0d5ef36b1c5e6d18a63643dff3a1155 Mon Sep 17 00:00:00 2001 From: wenxuan70 Date: Sun, 24 Nov 2024 17:53:23 +0800 Subject: [PATCH 01/15] Fix the dname_str method to cause conversion errors when the domain name length is 255 --- util/data/dname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/data/dname.c b/util/data/dname.c index 76b2ec7d6..cb78f5d63 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -654,7 +654,7 @@ void dname_str(uint8_t* dname, char* str) return; } len += lablen+1; - if(len >= LDNS_MAX_DOMAINLEN-1) { + if(len >= LDNS_MAX_DOMAINLEN) { *s++ = '&'; *s = 0; return; From 1cd2fb3b9d643ff66966d894877e99584a49b1e7 Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Mon, 2 Dec 2024 10:03:35 +0100 Subject: [PATCH 02/15] - For #1189, add unit tests for dname_str() and debug check the input buffer size. --- testcode/unitdname.c | 147 +++++++++++++++++++++++++++++++++++++++++++ util/data/dname.c | 14 +++-- 2 files changed, 156 insertions(+), 5 deletions(-) diff --git a/testcode/unitdname.c b/testcode/unitdname.c index 6769127b9..a3fa0c508 100644 --- a/testcode/unitdname.c +++ b/testcode/unitdname.c @@ -39,6 +39,7 @@ */ #include "config.h" +#include #include "util/log.h" #include "testcode/unitmain.h" #include "util/data/dname.h" @@ -858,6 +859,151 @@ dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf) sldns_buffer_flip(boundbuf); } +static void +dname_test_str(sldns_buffer* buff) +{ + char result[LDNS_MAX_DOMAINLEN], expect[LDNS_MAX_DOMAINLEN], *e; + size_t i; + unit_show_func("util/data/dname.c", "dname_str"); + + /* root ; expected OK */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\000", 1); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 1 ); + unit_assert( pkt_dname_len(buff) == 1 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( ".", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN - 1 ; expected OK */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 128 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 192 up to here */ + "\074abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567" /* 253 up to here */ + "\000" /* 254 up to here */ + , 254); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 254 ); + unit_assert( pkt_dname_len(buff) == 254 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567" + ".", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN ; expected OK */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 128 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 192 up to here */ + "\075abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678" /* 254 up to here */ + "\000" /* 255 up to here */ + , 255); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 255 ); + unit_assert( pkt_dname_len(buff) == 255 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678" + ".", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN + 1 ; expected to fail, output uses '&' on the latest label */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 128 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 192 up to here */ + "\076abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" /* 255 up to here */ + "\000" /* 256 up to here */ + , 256); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 256 ); + unit_assert( pkt_dname_len(buff) == 0 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "&", result) == 0 ); + + /* LDNS_MAX_LABELLEN + 1 ; expected to fail, output uses '#' on the offending label */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\100abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890a" /* 129 up to here */ + "\000" /* 130 up to here */ + , 130); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 130 ); + unit_assert( pkt_dname_len(buff) == 0 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "#", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN with single labels; expected OK */ + sldns_buffer_clear(buff); + for(i=0; i<=252; i+=2) + sldns_buffer_write(buff, "\001a", 2); + sldns_buffer_write_u8(buff, 0); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 255 ); + unit_assert( pkt_dname_len(buff) == 255 ); + dname_str(sldns_buffer_begin(buff), result); + e = expect; + for(i=0; i<=252; i+=2) { + *e++ = 'a'; + *e++ = '.'; + } + *e = '\0'; + unit_assert( strcmp(expect, result) == 0 ); + + /* LDNS_MAX_DOMAINLEN + 1 with single labels; expected to fail, output uses '&' on the latest label */ + sldns_buffer_clear(buff); + for(i=0; i<=250; i+=2) + sldns_buffer_write(buff, "\001a", 2); + sldns_buffer_write(buff, "\002ab", 3); + sldns_buffer_write_u8(buff, 0); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 256 ); + unit_assert( pkt_dname_len(buff) == 0 ); + dname_str(sldns_buffer_begin(buff), result); + e = expect; + for(i=0; i<=250; i+=2) { + *e++ = 'a'; + *e++ = '.'; + } + *e++ = '&'; + *e = '\0'; + unit_assert( strcmp(expect, result) == 0 ); + + /* Only alphas, numericals and '-', '_' and '*' are allowed in the output */ + for(i=1; i<=255; i++) { + if(isalnum(i) || i == '-' || i == '_' || i == '*') + continue; + sldns_buffer_clear(buff); + sldns_buffer_write_u8(buff, 1); + sldns_buffer_write_u8(buff, (uint8_t)i); + sldns_buffer_write_u8(buff, 0); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 3 ); + unit_assert( pkt_dname_len(buff) == 3); + dname_str(sldns_buffer_begin(buff), result); + if(strcmp( "?.", result) != 0 ) { + log_err("ASCII value '0x%lX' allowed in string output", i); + unit_assert(0); + } + } +} + void dname_test(void) { sldns_buffer* loopbuf = sldns_buffer_new(14); @@ -884,6 +1030,7 @@ void dname_test(void) dname_test_topdomain(); dname_test_valid(); dname_test_has_label(); + dname_test_str(buff); sldns_buffer_free(buff); sldns_buffer_free(loopbuf); sldns_buffer_free(boundbuf); diff --git a/util/data/dname.c b/util/data/dname.c index cb78f5d63..f08760e2f 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -644,24 +644,24 @@ void dname_str(uint8_t* dname, char* str) if(!dname || !*dname) { *s++ = '.'; *s = 0; - return; + goto out; } lablen = *dname++; while(lablen) { if(lablen > LDNS_MAX_LABELLEN) { *s++ = '#'; *s = 0; - return; + goto out; } len += lablen+1; if(len >= LDNS_MAX_DOMAINLEN) { *s++ = '&'; *s = 0; - return; + goto out; } while(lablen--) { - if(isalnum((unsigned char)*dname) - || *dname == '-' || *dname == '_' + if(isalnum((unsigned char)*dname) + || *dname == '-' || *dname == '_' || *dname == '*') *s++ = *(char*)dname++; else { @@ -673,6 +673,10 @@ void dname_str(uint8_t* dname, char* str) lablen = *dname++; } *s = 0; + +out: + log_assert(s - str < LDNS_MAX_DOMAINLEN); + return; } int From f46acec35f4199a19a8e5400f6cd08586fede8f5 Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Mon, 2 Dec 2024 11:53:56 +0100 Subject: [PATCH 03/15] - For #1189, homogenize the input buffer size for dname_str(). --- daemon/cachedump.c | 2 +- daemon/remote.c | 16 ++++---- daemon/worker.c | 4 +- iterator/iter_delegpt.c | 2 +- iterator/iter_fwd.c | 2 +- iterator/iter_hints.c | 2 +- iterator/iter_utils.c | 8 ++-- iterator/iterator.c | 12 +++--- libunbound/libworker.c | 2 +- pythonmod/interface.i | 2 +- respip/respip.c | 2 +- services/authzone.c | 84 +++++++++++++++++++------------------- services/cache/infra.c | 3 +- services/localzone.c | 8 ++-- services/outside_network.c | 6 +-- services/rpz.c | 15 +++---- testcode/fake_event.c | 2 +- testcode/unitneg.c | 2 +- testcode/unitzonemd.c | 2 +- util/data/dname.h | 5 ++- util/data/msgreply.c | 8 ++-- util/module.c | 8 ++-- util/net_help.c | 6 +-- validator/autotrust.c | 8 ++-- validator/val_anchor.c | 2 +- validator/validator.c | 2 +- 26 files changed, 110 insertions(+), 105 deletions(-) diff --git a/daemon/cachedump.c b/daemon/cachedump.c index a04b24e56..ba986c763 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -836,7 +836,7 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, struct delegpt* dp; struct dns_msg* msg; struct regional* region = worker->scratchpad; - char b[260]; + char b[LDNS_MAX_DOMAINLEN]; struct query_info qinfo; struct iter_hints_stub* stub; int nolock = 0; diff --git a/daemon/remote.c b/daemon/remote.c index 4d7cff4db..abba0f405 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2141,7 +2141,7 @@ static int ssl_print_name_dp(RES* ssl, const char* str, uint8_t* nm, uint16_t dclass, struct delegpt* dp) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; struct delegpt_ns* ns; struct delegpt_addr* a; int f = 0; @@ -2509,7 +2509,7 @@ do_insecure_remove(RES* ssl, struct worker* worker, char* arg) static void do_insecure_list(RES* ssl, struct worker* worker) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; struct trust_anchor* a; if(worker->env.anchors) { RBTREE_FOR(a, struct trust_anchor*, worker->env.anchors->tree) { @@ -2606,7 +2606,7 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m, } } else if(s == module_wait_subquery) { /* look in subs from mesh state to see what */ - char nm[257]; + char nm[LDNS_MAX_DOMAINLEN]; struct mesh_state_ref* sub; snprintf(buf, len, "%s wants", modname); l = strlen(buf); @@ -2636,7 +2636,7 @@ do_dump_requestlist(RES* ssl, struct worker* worker) struct mesh_area* mesh; struct mesh_state* m; int num = 0; - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; char timebuf[32]; char statbuf[10240]; if(!ssl_printf(ssl, "thread #%d\n", worker->thread_num)) @@ -2686,7 +2686,7 @@ dump_infra_host(struct lruhash_entry* e, void* arg) struct infra_key* k = (struct infra_key*)e->key; struct infra_data* d = (struct infra_data*)e->data; char ip_str[1024]; - char name[257]; + char name[LDNS_MAX_DOMAINLEN]; int port; if(a->ssl_failed) return; @@ -2953,7 +2953,7 @@ static void do_list_auth_zones(RES* ssl, struct auth_zones* az) { struct auth_zone* z; - char buf[257], buf2[256]; + char buf[LDNS_MAX_DOMAINLEN], buf2[256]; lock_rw_rdlock(&az->lock); RBTREE_FOR(z, struct auth_zone*, &az->ztree) { lock_rw_rdlock(&z->lock); @@ -2983,7 +2983,7 @@ static void do_list_local_zones(RES* ssl, struct local_zones* zones) { struct local_zone* z; - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; lock_rw_rdlock(&zones->lock); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); @@ -3094,7 +3094,7 @@ rate_list(struct lruhash_entry* e, void* arg) struct ratelimit_list_arg* a = (struct ratelimit_list_arg*)arg; struct rate_key* k = (struct rate_key*)e->key; struct rate_data* d = (struct rate_data*)e->data; - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; int lim = infra_find_ratelimit(a->infra, k->name, k->namelen); int max = infra_rate_max(d, a->now, a->backoff); if(a->all == 0) { diff --git a/daemon/worker.c b/daemon/worker.c index 713de3163..f44cd761a 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1082,7 +1082,7 @@ answer_notify(struct worker* w, struct query_info* qinfo, if(verbosity >= VERB_DETAIL) { char buf[380]; - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; char sr[25]; dname_str(qinfo->qname, zname); sr[0]=0; @@ -1413,7 +1413,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, return 0; } if(c->dnscrypt && !repinfo->is_dnscrypted) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; /* Check if this is unencrypted and asking for certs */ worker_check_request(c->buffer, worker, &check_result); if(check_result.value != 0) { diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c index c8b9a3ffe..be5bf482d 100644 --- a/iterator/iter_delegpt.c +++ b/iterator/iter_delegpt.c @@ -278,7 +278,7 @@ delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres, void delegpt_log(enum verbosity_value v, struct delegpt* dp) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; struct delegpt_ns* ns; struct delegpt_addr* a; size_t missing=0, numns=0, numaddr=0, numres=0, numavail=0; diff --git a/iterator/iter_fwd.c b/iterator/iter_fwd.c index b9d42553a..709911656 100644 --- a/iterator/iter_fwd.c +++ b/iterator/iter_fwd.c @@ -129,7 +129,7 @@ forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm, node->namelabs = nmlabs; node->dp = dp; if(!rbtree_insert(fwd->tree, &node->node)) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(nm, buf); log_err("duplicate forward zone %s ignored.", buf); delegpt_free_mlc(dp); diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 8b168271c..fb9d10413 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -181,7 +181,7 @@ hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp, node->noprime = (uint8_t)noprime; if(!name_tree_insert(&hints->tree, &node->node, dp->name, dp->namelen, dp->namelabs, c)) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(dp->name, buf); log_err("second hints for zone %s ignored.", buf); delegpt_free_mlc(dp); diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 5198e9ef2..e5cf13eca 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -1492,8 +1492,8 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf, int stub_no_cache = stub->dp->no_cache; lock_rw_unlock(&qstate->env->fwds->lock); if(stub_no_cache) { - char qname[255+1]; - char dpname[255+1]; + char qname[LDNS_MAX_DOMAINLEN]; + char dpname[LDNS_MAX_DOMAINLEN]; dname_str(qinf->qname, qname); dname_str(stub->dp->name, dpname); verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname); @@ -1520,8 +1520,8 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf, int dp_no_cache = dp->no_cache; lock_rw_unlock(&qstate->env->hints->lock); if(dp_no_cache) { - char qname[255+1]; - char dpname[255+1]; + char qname[LDNS_MAX_DOMAINLEN]; + char dpname[LDNS_MAX_DOMAINLEN]; dname_str(qinf->qname, qname); dname_str(dp->name, dpname); verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname); diff --git a/iterator/iterator.c b/iterator/iterator.c index fdba52ddb..ec70a267b 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1092,7 +1092,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq, /* cache is blacklisted and fallback, and we * already have an auth_zone dp */ if(verbosity>=VERB_ALGO) { - char buf[255+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(z->name, buf); verbose(VERB_ALGO, "auth_zone %s " "fallback because cache blacklisted", @@ -1109,7 +1109,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq, * validation failure, and the zone allows * fallback to the internet, query there. */ if(verbosity>=VERB_ALGO) { - char buf[255+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(z->name, buf); verbose(VERB_ALGO, "auth_zone %s " "fallback because cache blacklisted", @@ -2033,7 +2033,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, return 1; if(iq->depth > 0 && iq->target_count && iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "number of glue fetches %d", s, @@ -2041,7 +2041,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, return 2; } if(iq->dp_target_count > MAX_DP_TARGET_COUNT) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "number of glue fetches %d to a single delegation point", @@ -2252,7 +2252,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, } if(iq->depth > 0 && iq->target_count && iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "number of glue fetches %d", s, @@ -3044,7 +3044,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, target_count_increase_global_quota(iq, 1); if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] > MAX_GLOBAL_QUOTA) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "global quota on number of upstream queries %d", s, diff --git a/libunbound/libworker.c b/libunbound/libworker.c index da7d4c224..6b2bf7a3c 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -423,7 +423,7 @@ int libworker_bg(struct ub_ctx* ctx) static int fill_canon(struct ub_result* res, uint8_t* s) { - char buf[255+2]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(s, buf); res->canonname = strdup(buf); return res->canonname != 0; diff --git a/pythonmod/interface.i b/pythonmod/interface.i index 810b1449d..2040fb9e8 100644 --- a/pythonmod/interface.i +++ b/pythonmod/interface.i @@ -204,7 +204,7 @@ struct query_info { %inline %{ PyObject* dnameAsStr(PyObject* dname) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; buf[0] = '\0'; dname_str((uint8_t*)PyBytes_AsString(dname), buf); return PyString_FromString(buf); diff --git a/respip/respip.c b/respip/respip.c index db48f176e..c0ecba160 100644 --- a/respip/respip.c +++ b/respip/respip.c @@ -961,7 +961,7 @@ respip_rewrite_reply(const struct query_info* qinfo, struct sockaddr_storage ss; socklen_t ss_len = 0; char nm[256], ip[256]; - char qn[255+1]; + char qn[LDNS_MAX_DOMAINLEN]; if(!rdata2sockaddr(rep->rrsets[rrset_id]->entry.data, ntohs(rep->rrsets[rrset_id]->rk.type), rr_id, &ss, &ss_len)) snprintf(ip, sizeof(ip), "invalidRRdata"); else diff --git a/services/authzone.c b/services/authzone.c index 8019c491f..90fd0235e 100644 --- a/services/authzone.c +++ b/services/authzone.c @@ -1578,7 +1578,7 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg) cfg->chrootdir, strlen(cfg->chrootdir)) == 0) zfilename += strlen(cfg->chrootdir); if(verbosity >= VERB_ALGO) { - char nm[255+1]; + char nm[LDNS_MAX_DOMAINLEN]; dname_str(z->name, nm); verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm); } @@ -1942,7 +1942,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z, unsupported_reason = *reason; /* continue to check for valid ZONEMD */ if(verbosity >= VERB_ALGO) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zstr); verbose(VERB_ALGO, "auth-zone %s ZONEMD %d %d is unsupported: %s", zstr, (int)scheme, (int)hashalgo, *reason); } @@ -1950,7 +1950,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z, continue; } if(verbosity >= VERB_ALGO) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zstr); if(!*reason) verbose(VERB_ALGO, "auth-zone %s ZONEMD hash is correct", zstr); @@ -1973,7 +1973,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z, if(!*reason) *reason = "no ZONEMD records found"; if(verbosity >= VERB_ALGO) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zstr); verbose(VERB_ALGO, "auth-zone %s ZONEMD failed: %s", zstr, *reason); } @@ -4799,8 +4799,8 @@ log_rrlist_position(const char* label, struct auth_chunk* rr_chunk, { sldns_buffer pkt; size_t dlen; - uint8_t buf[256]; - char str[256]; + uint8_t buf[LDNS_MAX_DOMAINLEN]; + char str[LDNS_MAX_DOMAINLEN]; char typestr[32]; sldns_buffer_init_frm_data(&pkt, rr_chunk->data, rr_chunk->len); sldns_buffer_set_position(&pkt, (size_t)(rr_dname - @@ -5227,7 +5227,7 @@ xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env) cfg->chrootdir, strlen(cfg->chrootdir)) == 0) zfilename += strlen(cfg->chrootdir); if(verbosity >= VERB_ALGO) { - char nm[255+1]; + char nm[LDNS_MAX_DOMAINLEN]; dname_str(z->name, nm); verbose(VERB_ALGO, "write zonefile %s for %s", zfilename, nm); } @@ -5344,7 +5344,7 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env, /* holding z lock */ auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 0); if(z->zone_expired) { - char zname[256]; + char zname[LDNS_MAX_DOMAINLEN]; /* ZONEMD must have failed */ /* reacquire locks, so we hold xfr lock on exit of routine, * and both xfr and z again after releasing xfr for potential @@ -5376,7 +5376,7 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env, lock_rw_unlock(&z->lock); if(verbosity >= VERB_QUERY && xfr->have_zone) { - char zname[256]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname, (unsigned)xfr->serial); @@ -5438,7 +5438,7 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env) qinfo.local_alias = NULL; if(verbosity >= VERB_ALGO) { char buf1[512]; - char buf2[LDNS_MAX_DOMAINLEN+1]; + char buf2[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf2); snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup" " for task_transfer", buf2); @@ -5494,7 +5494,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) /* the ones that are not in addr format are supposed * to be looked up. The lookup has failed however, * so skip them */ - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); log_err("%s: failed lookup, cannot transfer from master %s", zname, master->host); @@ -5533,7 +5533,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) &addr, addrlen, -1, master->ssl, master->host, master->file, env->cfg); if(!xfr->task_transfer->cp) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "cannot create http cp " @@ -5542,7 +5542,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) } comm_timer_set(xfr->task_transfer->timer, &t); if(verbosity >= VERB_ALGO) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "auth zone %s transfer next HTTP fetch from %s started", zname, as); @@ -5565,7 +5565,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) env->scratch_buffer, -1, auth_name != NULL, auth_name); if(!xfr->task_transfer->cp) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "cannot create tcp cp connection for " @@ -5574,7 +5574,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) } comm_timer_set(xfr->task_transfer->timer, &t); if(verbosity >= VERB_ALGO) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname, @@ -5598,7 +5598,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env) * and that calls the callback just like a full * lookup and lookup failures also call callback */ if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s transfer next target lookup", zname); } @@ -5621,7 +5621,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env) xfr_transfer_nextmaster(xfr); } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s transfer failed, wait", zname); } @@ -5724,14 +5724,14 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, lookup_target, answer, wanted_qtype); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has nodata", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } } } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } @@ -5739,7 +5739,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, regional_free_all(temp); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup failed", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } @@ -6381,7 +6381,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, /* the ones that are not in addr format are supposed * to be looked up. The lookup has failed however, * so skip them */ - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); log_err("%s: failed lookup, cannot probe to master %s", zname, master->host); @@ -6423,7 +6423,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet, auth_xfer_probe_udp_callback, xfr, &addr, addrlen); if(!xfr->task_probe->cp) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "cannot create udp cp for " @@ -6443,7 +6443,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, /* send udp packet */ if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer, (struct sockaddr*)&addr, addrlen, 0)) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "failed to send soa probe for %s to %s", @@ -6451,7 +6451,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, return 0; } if(verbosity >= VERB_ALGO) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname, @@ -6482,7 +6482,7 @@ auth_xfer_probe_timer_callback(void* arg) } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s soa probe timeout", zname); } @@ -6530,7 +6530,7 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err, &serial)) { /* successful lookup */ if(verbosity >= VERB_ALGO) { - char buf[256]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf); verbose(VERB_ALGO, "auth zone %s: soa probe " "serial is %u", buf, (unsigned)serial); @@ -6569,14 +6569,14 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err, } } else { if(verbosity >= VERB_ALGO) { - char buf[256]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf); verbose(VERB_ALGO, "auth zone %s: bad reply to soa probe", buf); } } } else { if(verbosity >= VERB_ALGO) { - char buf[256]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf); verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf); } @@ -6633,7 +6633,7 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env) qinfo.local_alias = NULL; if(verbosity >= VERB_ALGO) { char buf1[512]; - char buf2[LDNS_MAX_DOMAINLEN+1]; + char buf2[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf2); snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup" " for task_probe", buf2); @@ -6679,7 +6679,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) * and that calls the callback just like a full * lookup and lookup failures also call callback */ if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s probe next target lookup", zname); } @@ -6692,7 +6692,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) * allow_notify addrs */ probe_copy_masters_for_allow_notify(xfr); if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s probe: notify addrs updated", zname); } @@ -6700,7 +6700,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) /* only wanted lookups for copy, stop probe and start wait */ xfr->task_probe->only_lookup = 0; if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname); } @@ -6726,7 +6726,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) if(xfr->task_probe->have_new_lease) { /* if zone not updated, start the wait timer again */ if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth_zone %s unchanged, new lease, wait", zname); } @@ -6737,7 +6737,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) xfr_set_timeout(xfr, env, 0, 0); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s soa probe failed, wait to retry", zname); } @@ -6787,14 +6787,14 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, lookup_target, answer, wanted_qtype); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has nodata", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } } } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } @@ -6802,7 +6802,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, regional_free_all(temp); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup failed", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } @@ -6976,7 +6976,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, if(!xfr->task_nextprobe->timer) { /* failed to malloc memory. likely zone transfer * also fails for that. skip the timeout */ - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); log_err("cannot allocate timer, no refresh for %s", zname); @@ -6997,7 +6997,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, xfr->task_probe->only_lookup = 1; } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s timeout in %d seconds", zname, (int)tv.tv_sec); @@ -7784,7 +7784,7 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level, va_list args; va_start(args, format); if(verbosity >= level) { - char str[255+1]; + char str[LDNS_MAX_DOMAINLEN]; char msg[MAXSYSLOGMSGLEN]; dname_str(name, str); vsnprintf(msg, sizeof(msg), format, args); @@ -7986,7 +7986,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z, static void auth_zone_zonemd_fail(struct auth_zone* z, struct module_env* env, char* reason, char* why_bogus, char** result) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; /* if fail: log reason, and depending on config also take action * and drop the zone, eg. it is gone from memory, set zone_expired */ dname_str(z->name, zstr); @@ -8432,7 +8432,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env) qinfo.local_alias = NULL; if(verbosity >= VERB_ALGO) { char buf1[512]; - char buf2[LDNS_MAX_DOMAINLEN+1]; + char buf2[LDNS_MAX_DOMAINLEN]; dname_str(z->name, buf2); snprintf(buf1, sizeof(buf1), "auth zone %s: lookup %s " "for zonemd verification", buf2, diff --git a/services/cache/infra.c b/services/cache/infra.c index 66b17c121..bb3ee87e9 100644 --- a/services/cache/infra.c +++ b/services/cache/infra.c @@ -1081,7 +1081,8 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, lock_rw_unlock(&entry->lock); if(premax <= lim && max > lim) { - char buf[257], qnm[257], ts[12], cs[12], ip[128]; + char buf[LDNS_MAX_DOMAINLEN], qnm[LDNS_MAX_DOMAINLEN]; + char ts[12], cs[12], ip[128]; dname_str(name, buf); dname_str(qinfo->qname, qnm); sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts)); diff --git a/services/localzone.c b/services/localzone.c index d21e0c48a..aa7138d6a 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -223,7 +223,7 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, lock_rw_wrlock(&z->lock); if(!rbtree_insert(&zones->ztree, &z->node)) { struct local_zone* oldz; - char str[256]; + char str[LDNS_MAX_DOMAINLEN]; dname_str(nm, str); log_warn("duplicate local-zone %s", str); lock_rw_unlock(&z->lock); @@ -1765,7 +1765,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo, struct sockaddr_storage* addr, socklen_t addrlen) { char ip[128], txt[512]; - char zname[LDNS_MAX_DOMAINLEN+1]; + char zname[LDNS_MAX_DOMAINLEN]; uint16_t port = ntohs(((struct sockaddr_in*)addr)->sin_port); dname_str(z->name, zname); addr_to_str(addr, addrlen, ip, sizeof(ip)); @@ -1875,7 +1875,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, return 0; } if(z && verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zname); verbose(VERB_ALGO, "using localzone %s %s from view %s", zname, local_zone_type2str(lzt), view->name); @@ -1897,7 +1897,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, z->override_tree, &tag, tagname, num_tags); lock_rw_unlock(&zones->lock); if(z && verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zname); verbose(VERB_ALGO, "using localzone %s %s", zname, local_zone_type2str(lzt)); diff --git a/services/outside_network.c b/services/outside_network.c index 58f1e6d58..b9475a368 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -1054,7 +1054,7 @@ reuse_move_writewait_away(struct outside_network* outnet, if(verbosity >= VERB_CLIENT && pend->query->pkt_len > 12+2+2 && LDNS_QDCOUNT(pend->query->pkt) > 0 && dname_valid(pend->query->pkt+12, pend->query->pkt_len-12)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(pend->query->pkt+12, buf); verbose(VERB_CLIENT, "reuse_move_writewait_away current %s %d bytes were written", buf, (int)pend->c->tcp_write_byte_count); @@ -1079,7 +1079,7 @@ reuse_move_writewait_away(struct outside_network* outnet, if(verbosity >= VERB_CLIENT && w->pkt_len > 12+2+2 && LDNS_QDCOUNT(w->pkt) > 0 && dname_valid(w->pkt+12, w->pkt_len-12)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(w->pkt+12, buf); verbose(VERB_CLIENT, "reuse_move_writewait_away item %s", buf); } @@ -2825,7 +2825,7 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len) lablen = *d++; } if(verbosity >= VERB_ALGO) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(qbuf+10, buf); verbose(VERB_ALGO, "qname perturbed to %s", buf); } diff --git a/services/rpz.c b/services/rpz.c index 3b92ee538..6658e89b7 100644 --- a/services/rpz.c +++ b/services/rpz.c @@ -666,7 +666,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, int newzone = 0; if(a == RPZ_INVALID_ACTION) { - char str[255+1]; + char str[LDNS_MAX_DOMAINLEN]; if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS || rrtype == LDNS_RR_TYPE_DNAME || rrtype == LDNS_RR_TYPE_DNSKEY || @@ -739,7 +739,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, static void rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; (void)dname_len; dname_str(dname, buf); verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf); @@ -1062,7 +1062,7 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, if(a == RPZ_INVALID_ACTION || rpz_action_to_respip_action(a) == respip_invalid) { - char str[255+1]; + char str[LDNS_MAX_DOMAINLEN]; dname_str(dname, str); verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s", str, rpz_action_to_string(a)); @@ -1633,7 +1633,7 @@ log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode, struct comm_reply* repinfo, struct module_qstate* ms, char* log_name) { char ip[128], txt[512], portstr[32]; - char dnamestr[LDNS_MAX_DOMAINLEN+1]; + char dnamestr[LDNS_MAX_DOMAINLEN]; uint16_t port = 0; if(dname) { dname_str(dname, dnamestr); @@ -2427,7 +2427,8 @@ rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones, match->dname = nameserver->name; match->dname_len = nameserver->namelen; if(verbosity >= VERB_ALGO) { - char nm[255+1], zn[255+1]; + char nm[LDNS_MAX_DOMAINLEN]; + char zn[LDNS_MAX_DOMAINLEN]; dname_str(match->dname, nm); dname_str(z->name, zn); if(strcmp(nm, zn) != 0) @@ -2581,7 +2582,7 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, } if(verbosity >= VERB_ALGO) { - char nm[255+1], zn[255+1]; + char nm[LDNS_MAX_DOMAINLEN], zn[LDNS_MAX_DOMAINLEN]; dname_str(is->qchase.qname, nm); dname_str(z->name, zn); if(strcmp(zn, nm) != 0) @@ -2758,7 +2759,7 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env, } if(verbosity >= VERB_ALGO) { - char nm[255+1], zn[255+1]; + char nm[LDNS_MAX_DOMAINLEN], zn[LDNS_MAX_DOMAINLEN]; dname_str(qinfo->qname, nm); dname_str(z->name, zn); if(strcmp(zn, nm) != 0) diff --git a/testcode/fake_event.c b/testcode/fake_event.c index 2f60b1381..def858706 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -1264,7 +1264,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); - char z[256]; + char z[LDNS_MAX_DOMAINLEN]; log_assert(pend); log_nametypeclass(VERB_OPS, "pending serviced query", qinfo->qname, qinfo->qtype, qinfo->qclass); diff --git a/testcode/unitneg.c b/testcode/unitneg.c index 59c4e8dcc..d1d03fc99 100644 --- a/testcode/unitneg.c +++ b/testcode/unitneg.c @@ -53,7 +53,7 @@ static int negverbose = 0; /** debug printout of neg cache */ static void print_neg_cache(struct val_neg_cache* neg) { - char buf[1024]; + char buf[LDNS_MAX_DOMAINLEN]; struct val_neg_zone* z; struct val_neg_data* d; printf("neg_cache print\n"); diff --git a/testcode/unitzonemd.c b/testcode/unitzonemd.c index a8a168e33..63dc13eda 100644 --- a/testcode/unitzonemd.c +++ b/testcode/unitzonemd.c @@ -111,7 +111,7 @@ static void zonemd_generate_test(const char* zname, char* zfile, digestdup[i] = toupper((unsigned char)digestdup[i]); } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zname); printf("zonemd generated for %s in %s with " "scheme=%d hashalgo=%d\n", zname, z->zonefile, diff --git a/util/data/dname.h b/util/data/dname.h index 15e28bd97..6e4cf7ea3 100644 --- a/util/data/dname.h +++ b/util/data/dname.h @@ -242,11 +242,12 @@ void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname); /** * Debug helper. Print dname to given string buffer (string buffer must - * be at least 255 chars + 1 for the 0, in printable form. + * be at least 255 chars, in printable form. * This may lose information (? for nonprintable characters, or & if * the name is too long, # for a bad label length). + * Upon return, the buffer will always have a terminating \0 value. * @param dname: uncompressed wireformat. - * @param str: buffer of 255+1 length. + * @param str: buffer of at least 255 length. */ void dname_str(uint8_t* dname, char* str); diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 78e4fb1c3..167581c0c 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -967,13 +967,9 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, int cached, struct sldns_buffer *rmsg, struct sockaddr_storage* daddr, enum comm_point_type tp) { - char qname_buf[LDNS_MAX_DOMAINLEN+1]; char clientip_buf[128]; char rcode_buf[16]; - char type_buf[16]; - char class_buf[16]; char dest_buf[160]; - size_t pktlen; uint16_t rcode = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(rmsg, 2)); if(verbosity < v) @@ -1022,6 +1018,10 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, else log_info("%s - - - %s - - -%s", clientip_buf, rcode_buf, dest_buf); } else { + char qname_buf[LDNS_MAX_DOMAINLEN]; + char type_buf[16]; + char class_buf[16]; + size_t pktlen; if(qinf->qname) dname_str(qinf->qname, qname_buf); else snprintf(qname_buf, sizeof(qname_buf), "null"); diff --git a/util/module.c b/util/module.c index 90a155b5e..d2c21b49d 100644 --- a/util/module.c +++ b/util/module.c @@ -135,7 +135,7 @@ char* errinf_to_str_bogus(struct module_qstate* qstate, struct regional* region) char* p = buf; size_t left = sizeof(buf); struct errinf_strlist* s; - char dname[LDNS_MAX_DOMAINLEN+1]; + char dname[LDNS_MAX_DOMAINLEN]; char t[16], c[16]; sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); @@ -178,7 +178,7 @@ char* errinf_to_str_servfail(struct module_qstate* qstate) char* p = buf; size_t left = sizeof(buf); struct errinf_strlist* s; - char dname[LDNS_MAX_DOMAINLEN+1]; + char dname[LDNS_MAX_DOMAINLEN]; char t[16], c[16]; sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); @@ -218,7 +218,7 @@ char* errinf_to_str_misc(struct module_qstate* qstate) void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) { char buf[1024]; - char dname[LDNS_MAX_DOMAINLEN+1]; + char dname[LDNS_MAX_DOMAINLEN]; char t[16], c[16]; if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr) return; @@ -232,7 +232,7 @@ void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname) { char b[1024]; - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname) return; dname_str(dname, buf); diff --git a/util/net_help.c b/util/net_help.c index 96b2b19a0..fbae91d9c 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -544,7 +544,7 @@ void log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, uint16_t type, uint16_t dclass) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; char t[12], c[12]; const char *ts, *cs; if(verbosity < v) @@ -575,7 +575,7 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, void log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; char t[12], c[12]; const char *ts, *cs; dname_str(name, buf); @@ -608,7 +608,7 @@ void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, { uint16_t port; const char* family = "unknown_family "; - char namebuf[LDNS_MAX_DOMAINLEN+1]; + char namebuf[LDNS_MAX_DOMAINLEN]; char dest[100]; int af = (int)((struct sockaddr_in*)addr)->sin_family; void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; diff --git a/validator/autotrust.c b/validator/autotrust.c index 36cdf3e0a..e28d728fd 100644 --- a/validator/autotrust.c +++ b/validator/autotrust.c @@ -353,7 +353,7 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, lock_basic_lock(&anchors->lock); if(!rbtree_insert(anchors->tree, &tp->node)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; lock_basic_unlock(&anchors->lock); dname_str(tp->name, buf); log_err("trust anchor for '%s' presented twice", buf); @@ -363,7 +363,7 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, return NULL; } if(!rbtree_insert(&anchors->autr->probe, &tp->autr->pnode)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; (void)rbtree_delete(anchors->tree, tp); lock_basic_unlock(&anchors->lock); dname_str(tp->name, buf); @@ -2288,7 +2288,9 @@ static void autr_debug_print_tp(struct trust_anchor* tp) { struct autr_ta* ta; - char buf[257]; + /* Note: buf is also used for autr_ctime_r but that only needs a size + * of 26, so LDNS_MAX_DOMAINLEN is enough. */ + char buf[LDNS_MAX_DOMAINLEN]; if(!tp->autr) return; dname_str(tp->name, buf); diff --git a/validator/val_anchor.c b/validator/val_anchor.c index 8466a8923..7a5256264 100644 --- a/validator/val_anchor.c +++ b/validator/val_anchor.c @@ -1018,7 +1018,7 @@ anchors_assemble_rrsets(struct val_anchors* anchors) ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); } if(nods == ta->numDS && nokey == ta->numDNSKEY) { - char b[257]; + char b[LDNS_MAX_DOMAINLEN]; dname_str(ta->name, b); log_warn("trust anchor %s has no supported algorithms," " the anchor is ignored (check if you need to" diff --git a/validator/validator.c b/validator/validator.c index 1a51dc270..7bfc46737 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -210,7 +210,7 @@ val_init(struct module_env* env, int id) struct trust_anchor* anchor = anchors_find_any_noninsecure( env->anchors); if(anchor) { - char b[LDNS_MAX_DOMAINLEN+2]; + char b[LDNS_MAX_DOMAINLEN]; dname_str(anchor->name, b); log_warn("validator: disable-edns-do is enabled, but there is a trust anchor for '%s'. Since DNSSEC could not work, the disable-edns-do setting is turned off. Continuing without it.", b); lock_basic_unlock(&anchor->lock); From c55490c1e6c1b1206457e1c1aae2dc418a60a873 Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Mon, 2 Dec 2024 12:28:11 +0100 Subject: [PATCH 04/15] - Fix #1193: log-servfail fails to log host SERVFAIL responses in Unbound 1.19.2 on Ubuntu 24.04.1 LTS, by not considering cached failures when trying to reply with expired data. --- services/mesh.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/mesh.c b/services/mesh.c index 5b9a02ae4..18a53b4a5 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -2203,8 +2203,13 @@ mesh_serve_expired_callback(void* arg) qstate->serve_expired_data->get_cached_answer)); msg = (*qstate->serve_expired_data->get_cached_answer)(qstate, lookup_qinfo, &is_expired); - if(!msg) + if(!msg || (FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR + && FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NXDOMAIN + && FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_YXDOMAIN)) { + /* We don't care for cached failure answers at this + * stage. */ return; + } /* Reset these in case we pass a second time from here. */ encode_rep = msg->rep; memset(&actinfo, 0, sizeof(actinfo)); From c124f67f33534a9cc7a52d951865872e887a92cc Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Mon, 2 Dec 2024 12:30:11 +0100 Subject: [PATCH 05/15] - For #1193, introduce log-servfail.tdir and cleanup the log-servfail setting from other tests. --- testdata/iter_failreply.rpl | 1 - testdata/iter_scrub_rr_length.rpl | 1 - testdata/log_servfail.tdir/log_servfail.conf | 27 +++++++++++ testdata/log_servfail.tdir/log_servfail.dsc | 16 +++++++ testdata/log_servfail.tdir/log_servfail.post | 10 ++++ testdata/log_servfail.tdir/log_servfail.pre | 21 +++++++++ testdata/log_servfail.tdir/log_servfail.test | 47 +++++++++++++++++++ testdata/rpz_val_block.rpl | 1 - testdata/serve_expired_0ttl_nodata.rpl | 1 - testdata/serve_expired_0ttl_nxdomain.rpl | 1 - testdata/serve_expired_0ttl_servfail.rpl | 1 - testdata/serve_expired_cached_servfail.rpl | 1 - .../serve_expired_cached_servfail_refresh.rpl | 1 - .../serve_expired_client_timeout_servfail.rpl | 1 - testdata/val_failure_dnskey.rpl | 1 - testdata/val_scrub_rr_length.rpl | 1 - 16 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 testdata/log_servfail.tdir/log_servfail.conf create mode 100644 testdata/log_servfail.tdir/log_servfail.dsc create mode 100644 testdata/log_servfail.tdir/log_servfail.post create mode 100644 testdata/log_servfail.tdir/log_servfail.pre create mode 100644 testdata/log_servfail.tdir/log_servfail.test diff --git a/testdata/iter_failreply.rpl b/testdata/iter_failreply.rpl index 393714196..e8ad4dd26 100644 --- a/testdata/iter_failreply.rpl +++ b/testdata/iter_failreply.rpl @@ -3,7 +3,6 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no - log-servfail: yes stub-zone: name: "." diff --git a/testdata/iter_scrub_rr_length.rpl b/testdata/iter_scrub_rr_length.rpl index 2ef73c2fe..ee7579f9c 100644 --- a/testdata/iter_scrub_rr_length.rpl +++ b/testdata/iter_scrub_rr_length.rpl @@ -5,7 +5,6 @@ server: minimal-responses: no rrset-roundrobin: no ede: yes - log-servfail: yes stub-zone: name: "." diff --git a/testdata/log_servfail.tdir/log_servfail.conf b/testdata/log_servfail.tdir/log_servfail.conf new file mode 100644 index 000000000..2d7c34e68 --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.conf @@ -0,0 +1,27 @@ +server: + verbosity: 0 + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + use-caps-for-id: no + port: @SERVER_PORT@ + interface: 127.0.0.1 + outbound-msg-retry: 0 + + log-servfail: yes + +forward-zone: + name: "a.servfail" + forward-addr: 127.0.0.1@@SERVER_PORT@ + +forward-zone: + name: "b.servfail" + forward-addr: 127.0.0.1@@SERVER_PORT@ + +remote-control: + control-enable: yes + control-port: @CONTROL_PORT@ + control-use-cert: no diff --git a/testdata/log_servfail.tdir/log_servfail.dsc b/testdata/log_servfail.tdir/log_servfail.dsc new file mode 100644 index 000000000..cf4f455aa --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.dsc @@ -0,0 +1,16 @@ +BaseName: log_servfail +Version: 1.0 +Description: Check the log_servfail option +CreationDate: Fri 29 Nov 11:00:00 CEST 2024 +Maintainer: +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: log_servfail.pre +Post: log_servfail.post +Test: log_servfail.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/log_servfail.tdir/log_servfail.post b/testdata/log_servfail.tdir/log_servfail.post new file mode 100644 index 000000000..a7bd0e88f --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.post @@ -0,0 +1,10 @@ +# #-- log_servfail.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +kill_from_pidfile "unbound.pid" +cat unbound.log diff --git a/testdata/log_servfail.tdir/log_servfail.pre b/testdata/log_servfail.tdir/log_servfail.pre new file mode 100644 index 000000000..540594808 --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.pre @@ -0,0 +1,21 @@ +# #-- log_servfail.pre--# +PRE="../.." +. ../common.sh + +get_random_port 2 +SERVER_PORT=$RND_PORT +CONTROL_PORT=$(($RND_PORT + 1)) +echo "SERVER_PORT=$SERVER_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test + +# make config file +sed \ + -e 's/@SERVER_PORT\@/'$SERVER_PORT'/' \ + -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' \ + < log_servfail.conf > ub.conf + +# start unbound in the background +$PRE/unbound -d -c ub.conf > unbound.log 2>&1 & + +cat .tpkg.var.test +wait_unbound_up unbound.log diff --git a/testdata/log_servfail.tdir/log_servfail.test b/testdata/log_servfail.tdir/log_servfail.test new file mode 100644 index 000000000..a6156ba04 --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.test @@ -0,0 +1,47 @@ +# #-- cookie_file.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test +PRE="../.." +. ../common.sh + +outfile=dig.out + +teststep "Check if log-servfail logs to output for iterator error" +dig a.servfail @127.0.0.1 -p $SERVER_PORT > $outfile +if ! grep "SERVFAIL" $outfile +then + cat $outfile + echo "Did not get a SERVFAIL response" + exit 1 +fi +if ! grep "SERVFAIL $outfile +if ! grep "SERVFAIL" $outfile +then + cat $outfile + echo "Did not get a SERVFAIL response" + exit 1 +fi +if ! grep "SERVFAIL Date: Tue, 3 Dec 2024 11:58:06 +0100 Subject: [PATCH 06/15] Changelog entry for #1189, #1197: - Merge #1189: Fix the dname_str method to cause conversion errors when the domain name length is 255. - Merge #1197: dname_str() fixes. --- doc/Changelog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/Changelog b/doc/Changelog index 0403e0c10..d96ae8020 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,8 @@ +3 December 2024: Yorgos + - Merge #1189: Fix the dname_str method to cause conversion errors + when the domain name length is 255. + - Merge #1197: dname_str() fixes. + 22 November 2024: Yorgos - Fix #1175: serve-expired does not adhere to secure-by-default principle. The default value of serve-expired-client-timeout From 9de159b96bb218ad0613055de77302d5aad15b0d Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Tue, 3 Dec 2024 13:09:51 +0100 Subject: [PATCH 07/15] - For #1175, the default value of serve-expired-ttl is set to 86400 (1 day) as suggested by RFC8767. --- doc/Changelog | 2 ++ doc/example.conf.in | 2 +- doc/unbound.conf.5.in | 9 +++++---- util/config_file.c | 2 +- util/data/msgreply.c | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index d96ae8020..331d03c55 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -2,6 +2,8 @@ - Merge #1189: Fix the dname_str method to cause conversion errors when the domain name length is 255. - Merge #1197: dname_str() fixes. + - For #1175, the default value of serve-expired-ttl is set to 86400 + (1 day) as suggested by RFC8767. 22 November 2024: Yorgos - Fix #1175: serve-expired does not adhere to secure-by-default diff --git a/doc/example.conf.in b/doc/example.conf.in index e0ee39ad4..33e12f180 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -737,7 +737,7 @@ server: # # Limit serving of expired responses to configured seconds after # expiration. 0 disables the limit. - # serve-expired-ttl: 0 + # serve-expired-ttl: 86400 # # Set the TTL of expired records to the serve-expired-ttl value after a # failed attempt to retrieve the record from upstream. This makes sure diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index cf6f14915..4d1fb13f8 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -1408,10 +1408,11 @@ out or is taking more than serve\-expired\-client\-timeout to resolve. Default is "no". .TP .B serve\-expired\-ttl: \fI -Limit serving of expired responses to configured seconds after expiration. 0 -disables the limit. This option only applies when \fBserve\-expired\fR is -enabled. A suggested value per RFC 8767 is between -86400 (1 day) and 259200 (3 days). The default is 0. +Limit serving of expired responses to configured seconds after expiration. +0 disables the limit. +This option only applies when \fBserve\-expired\fR is enabled. +A suggested value per RFC 8767 is between 86400 (1 day) and 259200 (3 days). +The default is 86400. .TP .B serve\-expired\-ttl\-reset: \fI Set the TTL of expired records to the \fBserve\-expired\-ttl\fR value after a diff --git a/util/config_file.c b/util/config_file.c index c1c55c529..58567dccc 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -280,7 +280,7 @@ config_create(void) cfg->ignore_cd = 0; cfg->disable_edns_do = 0; cfg->serve_expired = 0; - cfg->serve_expired_ttl = 0; + cfg->serve_expired_ttl = 86400; cfg->serve_expired_ttl_reset = 0; cfg->serve_expired_reply_ttl = 30; cfg->serve_expired_client_timeout = 1800; diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 167581c0c..530eee701 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -66,7 +66,7 @@ time_t MIN_NEG_TTL = 0; /** If we serve expired entries and prefetch them */ int SERVE_EXPIRED = 0; /** Time to serve records after expiration */ -time_t SERVE_EXPIRED_TTL = 0; +time_t SERVE_EXPIRED_TTL = 86400; /** Reset serve expired TTL after failed update attempt */ time_t SERVE_EXPIRED_TTL_RESET = 0; /** TTL to use for expired records */ From be92752368bdf01313f697e12299e049c634fca6 Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Tue, 3 Dec 2024 14:05:12 +0100 Subject: [PATCH 08/15] - Merge #1198: Fix log-servfail with serve expired and no useful cache contents. --- doc/Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/Changelog b/doc/Changelog index 331d03c55..fdcf53f3c 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -4,6 +4,8 @@ - Merge #1197: dname_str() fixes. - For #1175, the default value of serve-expired-ttl is set to 86400 (1 day) as suggested by RFC8767. + - Merge #1198: Fix log-servfail with serve expired and no useful cache + contents. 22 November 2024: Yorgos - Fix #1175: serve-expired does not adhere to secure-by-default From b4a9c8bb0573b565375db5efd8e7f849667fa881 Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Tue, 3 Dec 2024 14:10:17 +0100 Subject: [PATCH 09/15] - Safeguard alias loop while looking in the cache for expired answers. --- doc/Changelog | 1 + services/mesh.c | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index fdcf53f3c..5e625dc97 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -6,6 +6,7 @@ (1 day) as suggested by RFC8767. - Merge #1198: Fix log-servfail with serve expired and no useful cache contents. + - Safeguard alias loop while looking in the cache for expired answers. 22 November 2024: Yorgos - Fix #1175: serve-expired does not adhere to secure-by-default diff --git a/services/mesh.c b/services/mesh.c index 18a53b4a5..a25094d12 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -2183,7 +2183,7 @@ mesh_serve_expired_callback(void* arg) struct timeval tv = {0, 0}; int must_validate = (!(qstate->query_flags&BIT_CD) || qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate; - int i = 0; + int i = 0, for_count; int is_expired; if(!qstate->serve_expired_data) return; verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data"); @@ -2196,9 +2196,10 @@ mesh_serve_expired_callback(void* arg) "Serve expired: Not allowed to look into cache for stale"); return; } - /* The following while is used instead of the `goto lookup_cache` - * like in the worker. */ - while(1) { + /* The following for is used instead of the `goto lookup_cache` + * like in the worker. This loop should get max 2 passes if we need to + * do any aliasing. */ + for(for_count = 0; for_count < 2; for_count++) { fptr_ok(fptr_whitelist_serve_expired_lookup( qstate->serve_expired_data->get_cached_answer)); msg = (*qstate->serve_expired_data->get_cached_answer)(qstate, From 61d7250b96577731be5e000d6e7eea9acbf26413 Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Tue, 3 Dec 2024 14:20:33 +0100 Subject: [PATCH 10/15] Create the SSL_CTX for QUIC before chroot and privilege drop (#1187) Fixes #1185 by creating the SSL_CTX for QUIC before chroot and privilege drop, just like the other SSL_CTX creations. --------- Co-authored-by: Wouter Wijngaards --- daemon/daemon.c | 3 ++ daemon/daemon.h | 2 ++ daemon/unbound.c | 13 +++++-- daemon/worker.c | 4 +-- services/listen_dnsport.c | 71 +++++++++++++++++++-------------------- services/listen_dnsport.h | 21 +++++++----- testcode/fake_event.c | 5 ++- testcode/testbound.c | 6 ++++ util/net_help.h | 2 +- util/netevent.c | 71 +++++---------------------------------- util/netevent.h | 13 ++----- winrc/win_svc.c | 5 +++ 12 files changed, 90 insertions(+), 126 deletions(-) diff --git a/daemon/daemon.c b/daemon/daemon.c index 1c8272b14..9e1d5d4f7 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -956,6 +956,9 @@ daemon_delete(struct daemon* daemon) listen_sslctx_delete_ticket_keys(); SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx); SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx); +#endif +#ifdef HAVE_NGTCP2 + SSL_CTX_free((SSL_CTX*)daemon->quic_sslctx); #endif free(daemon); /* lex cleanup */ diff --git a/daemon/daemon.h b/daemon/daemon.h index fc1bde713..f93887e3d 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -99,6 +99,8 @@ struct daemon { struct daemon_remote* rc; /** ssl context for listening to dnstcp over ssl, and connecting ssl */ void* listen_sslctx, *connect_sslctx; + /** ssl context for listening to quic */ + void* quic_sslctx; /** num threads allocated */ int num; /** num threads allocated in the previous config or 0 at first */ diff --git a/daemon/unbound.c b/daemon/unbound.c index 306fe6caf..f394fbde3 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -494,8 +494,9 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, fatal_exit("could not set up remote-control"); if(cfg->ssl_service_key && cfg->ssl_service_key[0]) { if(!(daemon->listen_sslctx = listen_sslctx_create( - cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) + cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) { fatal_exit("could not set up listen SSL_CTX"); + } if(cfg->tls_ciphers && cfg->tls_ciphers[0]) { if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) { fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers); @@ -507,18 +508,24 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites); } } -#endif +#endif /* HAVE_SSL_CTX_SET_CIPHERSUITES */ if(cfg->tls_session_ticket_keys.first && cfg->tls_session_ticket_keys.first->str[0] != 0) { if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) { fatal_exit("could not set session ticket SSL_CTX"); } } +#ifdef HAVE_NGTCP2 + if(!(daemon->quic_sslctx = quic_sslctx_create( + cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) { + fatal_exit("could not set up quic SSL_CTX"); + } +#endif /* HAVE_NGTCP2 */ } if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, cfg->tls_cert_bundle, cfg->tls_win_cert))) fatal_exit("could not set up connect SSL_CTX"); -#endif +#endif /* HAVE_SSL */ /* init syslog (as root) if needed, before daemonize, otherwise * a fork error could not be printed since daemonize closed stderr.*/ diff --git a/daemon/worker.c b/daemon/worker.c index f44cd761a..413abdb87 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -2174,9 +2174,9 @@ worker_init(struct worker* worker, struct config_file *cfg, cfg->harden_large_queries, cfg->http_max_streams, cfg->http_endpoint, cfg->http_notls_downstream, worker->daemon->tcl, worker->daemon->listen_sslctx, + worker->daemon->quic_sslctx, dtenv, worker->daemon->doq_table, worker->env.rnd, - cfg->ssl_service_key, cfg->ssl_service_pem, cfg, - worker_handle_request, worker); + cfg, worker_handle_request, worker); if(!worker->front) { log_err("could not create listening sockets"); worker_delete(worker); diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 5dbac3650..bdd14b04a 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -1523,9 +1523,9 @@ listen_create(struct comm_base* base, struct listen_port* ports, size_t bufsize, int tcp_accept_count, int tcp_idle_timeout, int harden_large_queries, uint32_t http_max_streams, char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit, - void* sslctx, struct dt_env* dtenv, struct doq_table* doq_table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg, + void* sslctx, void* quic_sslctx, struct dt_env* dtenv, + struct doq_table* doq_table, + struct ub_randstate* rnd,struct config_file* cfg, comm_point_callback_type* cb, void *cb_arg) { struct listen_dnsport* front = (struct listen_dnsport*) @@ -1558,8 +1558,7 @@ listen_create(struct comm_base* base, struct listen_port* ports, #endif cp = comm_point_create_doq(base, ports->fd, front->udp_buff, cb, cb_arg, ports->socket, - doq_table, rnd, ssl_service_key, - ssl_service_pem, cfg); + doq_table, rnd, quic_sslctx, cfg); } else if(ports->ftype == listen_type_tcp || ports->ftype == listen_type_tcp_dnscrypt) { cp = comm_point_create_tcp(base, ports->fd, @@ -1620,10 +1619,13 @@ listen_create(struct comm_base* base, struct listen_port* ports, (ports->ftype == listen_type_udpancil) || (ports->ftype == listen_type_tcp_dnscrypt) || (ports->ftype == listen_type_udp_dnscrypt) || - (ports->ftype == listen_type_udpancil_dnscrypt)) + (ports->ftype == listen_type_udpancil_dnscrypt)) { cp->ssl = NULL; - else + } else if(ports->ftype == listen_type_doq) { + cp->ssl = quic_sslctx; + } else { cp->ssl = sslctx; + } cp->dtenv = dtenv; cp->do_not_close = 1; #ifdef USE_DNSCRYPT @@ -4598,10 +4600,9 @@ doq_alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, return SSL_TLSEXT_ERR_ALERT_FATAL; } -/** create new tls session for server doq connection */ -static SSL_CTX* -doq_ctx_server_setup(struct doq_server_socket* doq_socket) +void* quic_sslctx_create(char* key, char* pem, char* verifypem) { +#ifdef HAVE_NGTCP2 char* sid_ctx = "unbound server"; #ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT SSL_QUIC_METHOD* quic_method; @@ -4611,6 +4612,16 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) log_crypto_err("Could not SSL_CTX_new"); return NULL; } + if(!key || key[0] == 0) { + log_err("doq: error, no tls-service-key file specified"); + SSL_CTX_free(ctx); + return NULL; + } + if(!pem || pem[0] == 0) { + log_err("doq: error, no tls-service-pem file specified"); + SSL_CTX_free(ctx); + return NULL; + } SSL_CTX_set_options(ctx, (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) | SSL_OP_SINGLE_ECDH_USE | @@ -4623,43 +4634,37 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) SSL_CTX_set_alpn_select_cb(ctx, doq_alpn_select_cb, NULL); #endif SSL_CTX_set_default_verify_paths(ctx); - if(!SSL_CTX_use_certificate_chain_file(ctx, - doq_socket->ssl_service_pem)) { - log_err("doq: error for cert file: %s", - doq_socket->ssl_service_pem); + if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { + log_err("doq: error for cert file: %s", pem); log_crypto_err("doq: error in " "SSL_CTX_use_certificate_chain_file"); SSL_CTX_free(ctx); return NULL; } - if(!SSL_CTX_use_PrivateKey_file(ctx, doq_socket->ssl_service_key, - SSL_FILETYPE_PEM)) { - log_err("doq: error for private key file: %s", - doq_socket->ssl_service_key); + if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { + log_err("doq: error for private key file: %s", key); log_crypto_err("doq: error in SSL_CTX_use_PrivateKey_file"); SSL_CTX_free(ctx); return NULL; } if(!SSL_CTX_check_private_key(ctx)) { - log_err("doq: error for key file: %s", - doq_socket->ssl_service_key); + log_err("doq: error for key file: %s", key); log_crypto_err("doq: error in SSL_CTX_check_private_key"); SSL_CTX_free(ctx); return NULL; } SSL_CTX_set_session_id_context(ctx, (void*)sid_ctx, strlen(sid_ctx)); - if(doq_socket->ssl_verify_pem && doq_socket->ssl_verify_pem[0]) { - if(!SSL_CTX_load_verify_locations(ctx, - doq_socket->ssl_verify_pem, NULL)) { + if(verifypem && verifypem[0]) { + if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { log_err("doq: error for verify pem file: %s", - doq_socket->ssl_verify_pem); + verifypem); log_crypto_err("doq: error in " "SSL_CTX_load_verify_locations"); SSL_CTX_free(ctx); return NULL; } SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( - doq_socket->ssl_verify_pem)); + verifypem)); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER| SSL_VERIFY_CLIENT_ONCE| SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); @@ -4672,7 +4677,7 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) SSL_CTX_free(ctx); return NULL; } -#else +#else /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */ /* The quic_method needs to remain valid during the SSL_CTX * lifetime, so we allocate it. It is freed with the * doq_server_socket. */ @@ -4690,6 +4695,10 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) SSL_CTX_set_quic_method(ctx, doq_socket->quic_method); #endif return ctx; +#else /* HAVE_NGTCP2 */ + (void)key; (void)pem; (void)verifypem; + return NULL; +#endif /* HAVE_NGTCP2 */ } /** Get the ngtcp2_conn from ssl userdata of type ngtcp2_conn_ref */ @@ -4720,16 +4729,6 @@ doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn) return ssl; } -/** setup the doq_socket server tls context */ -int -doq_socket_setup_ctx(struct doq_server_socket* doq_socket) -{ - doq_socket->ctx = doq_ctx_server_setup(doq_socket); - if(!doq_socket->ctx) - return 0; - return 1; -} - int doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen, uint8_t* ocid, size_t ocidlen, const uint8_t* token, size_t tokenlen) diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h index c29f4d72b..629f20bd4 100644 --- a/services/listen_dnsport.h +++ b/services/listen_dnsport.h @@ -195,11 +195,10 @@ int resolve_interface_names(char** ifs, int num_ifs, * @param http_notls: no TLS for http downstream * @param tcp_conn_limit: TCP connection limit info. * @param sslctx: nonNULL if ssl context. + * @param quic_sslctx: nonNULL if quic ssl context. * @param dtenv: nonNULL if dnstap enabled. * @param doq_table: the doq connection table, with shared information. * @param rnd: random state. - * @param ssl_service_key: the SSL service key file. - * @param ssl_service_pem: the SSL service pem file. * @param cfg: config file struct. * @param cb: callback function when a request arrives. It is passed * the packet and user argument. Return true to send a reply. @@ -211,9 +210,9 @@ listen_create(struct comm_base* base, struct listen_port* ports, size_t bufsize, int tcp_accept_count, int tcp_idle_timeout, int harden_large_queries, uint32_t http_max_streams, char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit, - void* sslctx, struct dt_env* dtenv, struct doq_table* doq_table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg, + void* sslctx, void* quic_sslctx, struct dt_env* dtenv, + struct doq_table* doq_table, + struct ub_randstate* rnd,struct config_file* cfg, comm_point_callback_type* cb, void *cb_arg); /** @@ -512,6 +511,15 @@ struct doq_table { size_t current_size; }; +/** + * create SSL context for QUIC + * @param key: private key file. + * @param pem: public key cert. + * @param verifypem: if nonNULL, verifylocation file. + * return SSL_CTX* or NULL on failure (logged). + */ +void* quic_sslctx_create(char* key, char* pem, char* verifypem); + /** create doq table */ struct doq_table* doq_table_create(struct config_file* cfg, struct ub_randstate* rnd); @@ -712,9 +720,6 @@ int doq_timer_cmp(const void* key1, const void* key2); /** compare function of doq_stream */ int doq_stream_cmp(const void* key1, const void* key2); -/** setup the doq_socket server tls context */ -int doq_socket_setup_ctx(struct doq_server_socket* doq_socket); - /** setup the doq connection callbacks, and settings. */ int doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen, uint8_t* ocid, size_t ocidlen, const uint8_t* token, size_t tokenlen); diff --git a/testcode/fake_event.c b/testcode/fake_event.c index def858706..be61ed5c6 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -938,11 +938,10 @@ listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports), char* ATTR_UNUSED(http_endpoint), int ATTR_UNUSED(http_notls), struct tcl_list* ATTR_UNUSED(tcp_conn_limit), - void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv), + void* ATTR_UNUSED(sslctx), void* ATTR_UNUSED(quic_ssl), + struct dt_env* ATTR_UNUSED(dtenv), struct doq_table* ATTR_UNUSED(table), struct ub_randstate* ATTR_UNUSED(rnd), - const char* ATTR_UNUSED(ssl_service_key), - const char* ATTR_UNUSED(ssl_service_pem), struct config_file* ATTR_UNUSED(cfg), comm_point_callback_type* cb, void *cb_arg) { diff --git a/testcode/testbound.c b/testcode/testbound.c index 442e23434..f9ea86e69 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -602,6 +602,12 @@ void listen_desetup_locks(void) } #ifdef HAVE_NGTCP2 +void* quic_sslctx_create(char* ATTR_UNUSED(key), char* ATTR_UNUSED(pem), + char* ATTR_UNUSED(verifypem)) +{ + return NULL; +} + void comm_point_doq_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) { diff --git a/util/net_help.h b/util/net_help.h index eba38cee0..4365c9a6a 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -488,7 +488,7 @@ int listen_sslctx_setup(void* ctxt); */ void listen_sslctx_setup_2(void* ctxt); -/** +/** * create SSL listen context * @param key: private key file. * @param pem: public key cert. diff --git a/util/netevent.c b/util/netevent.c index 9181d3e4a..8f64278c3 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -2687,8 +2687,8 @@ comm_point_doq_callback(int fd, short event, void* arg) /** create new doq server socket structure */ static struct doq_server_socket* doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, - const char* ssl_service_key, const char* ssl_service_pem, - struct comm_point* c, struct comm_base* base, struct config_file* cfg) + const void* quic_sslctx, struct comm_point* c, struct comm_base* base, + struct config_file* cfg) { size_t doq_buffer_size = 4096; /* bytes buffer size, for one packet. */ struct doq_server_socket* doq_socket; @@ -2699,69 +2699,29 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, doq_socket->table = table; doq_socket->rnd = rnd; doq_socket->validate_addr = 1; - if(ssl_service_key == NULL || ssl_service_key[0]==0) { - log_err("doq server socket create: no tls-service-key"); - free(doq_socket); - return NULL; - } - if(ssl_service_pem == NULL || ssl_service_pem[0]==0) { - log_err("doq server socket create: no tls-service-pem"); - free(doq_socket); - return NULL; - } - doq_socket->ssl_service_key = strdup(ssl_service_key); - if(!doq_socket->ssl_service_key) { - free(doq_socket); - return NULL; - } - doq_socket->ssl_service_pem = strdup(ssl_service_pem); - if(!doq_socket->ssl_service_pem) { - free(doq_socket->ssl_service_key); - free(doq_socket); - return NULL; - } - doq_socket->ssl_verify_pem = NULL; /* the doq_socket has its own copy of the static secret, as * well as other config values, so that they do not need table.lock */ doq_socket->static_secret_len = table->static_secret_len; doq_socket->static_secret = memdup(table->static_secret, table->static_secret_len); if(!doq_socket->static_secret) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); - free(doq_socket); - return NULL; - } - if(!doq_socket_setup_ctx(doq_socket)) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); - free(doq_socket->static_secret); free(doq_socket); return NULL; } + doq_socket->ctx = (SSL_CTX*)quic_sslctx; doq_socket->idle_timeout = table->idle_timeout; doq_socket->sv_scidlen = table->sv_scidlen; doq_socket->cp = c; doq_socket->pkt_buf = sldns_buffer_new(doq_buffer_size); if(!doq_socket->pkt_buf) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); free(doq_socket); return NULL; } doq_socket->blocked_pkt = sldns_buffer_new( sldns_buffer_capacity(doq_socket->pkt_buf)); if(!doq_socket->pkt_buf) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); sldns_buffer_free(doq_socket->pkt_buf); free(doq_socket); return NULL; @@ -2769,11 +2729,7 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, doq_socket->blocked_paddr = calloc(1, sizeof(*doq_socket->blocked_paddr)); if(!doq_socket->blocked_paddr) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); sldns_buffer_free(doq_socket->pkt_buf); sldns_buffer_free(doq_socket->blocked_pkt); free(doq_socket); @@ -2781,11 +2737,7 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, } doq_socket->timer = comm_timer_create(base, doq_timer_cb, doq_socket); if(!doq_socket->timer) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); sldns_buffer_free(doq_socket->pkt_buf); sldns_buffer_free(doq_socket->blocked_pkt); free(doq_socket->blocked_paddr); @@ -2805,13 +2757,9 @@ doq_server_socket_delete(struct doq_server_socket* doq_socket) if(!doq_socket) return; free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); #ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT free(doq_socket->quic_method); #endif - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); sldns_buffer_free(doq_socket->pkt_buf); sldns_buffer_free(doq_socket->blocked_pkt); free(doq_socket->blocked_paddr); @@ -5862,8 +5810,8 @@ struct comm_point* comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer, comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket, struct doq_table* table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg) + struct ub_randstate* rnd, const void* quic_sslctx, + struct config_file* cfg) { #ifdef HAVE_NGTCP2 struct comm_point* c = (struct comm_point*)calloc(1, @@ -5900,15 +5848,13 @@ comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer, c->dnscrypt = 0; c->dnscrypt_buffer = NULL; #endif -#ifdef HAVE_NGTCP2 - c->doq_socket = doq_server_socket_create(table, rnd, ssl_service_key, - ssl_service_pem, c, base, cfg); + c->doq_socket = doq_server_socket_create(table, rnd, quic_sslctx, c, + base, cfg); if(!c->doq_socket) { log_err("could not create doq comm_point"); comm_point_delete(c); return NULL; } -#endif c->inuse = 0; c->callback = callback; c->cb_arg = callback_arg; @@ -5940,8 +5886,7 @@ comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer, (void)socket; (void)rnd; (void)table; - (void)ssl_service_key; - (void)ssl_service_pem; + (void)quic_sslctx; (void)cfg; sock_close(fd); return NULL; diff --git a/util/netevent.h b/util/netevent.h index acc4887b1..a9deeecea 100644 --- a/util/netevent.h +++ b/util/netevent.h @@ -593,8 +593,7 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base, * @param socket: and opened socket properties will be passed to your callback function. * @param table: the doq connection table for the host. * @param rnd: random generator to use. - * @param ssl_service_key: the ssl service key file. - * @param ssl_service_pem: the ssl service pem file. + * @param quic_sslctx: the quic ssl context. * @param cfg: config file struct. * @return: returns the allocated communication point. NULL on error. * Sets timeout to NULL. Turns off TCP options. @@ -603,8 +602,8 @@ struct comm_point* comm_point_create_doq(struct comm_base* base, int fd, struct sldns_buffer* buffer, comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket, struct doq_table* table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg); + struct ub_randstate* rnd, const void* quic_sslctx, + struct config_file* cfg); /** * Create a TCP listener comm point. Calls malloc. @@ -1045,12 +1044,6 @@ struct doq_server_socket { struct ub_randstate* rnd; /** if address validation is enabled */ uint8_t validate_addr; - /** the ssl service key file */ - char* ssl_service_key; - /** the ssl service pem file */ - char* ssl_service_pem; - /** the ssl verify pem file */ - char* ssl_verify_pem; /** the server scid length */ int sv_scidlen; /** the idle timeout in nanoseconds */ diff --git a/winrc/win_svc.c b/winrc/win_svc.c index 49d4251fa..bd28bd206 100644 --- a/winrc/win_svc.c +++ b/winrc/win_svc.c @@ -366,6 +366,11 @@ service_init(int r, struct daemon** d, struct config_file** c) if(!(daemon->listen_sslctx = listen_sslctx_create( cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) fatal_exit("could not set up listen SSL_CTX"); +#ifdef HAVE_NGTCP2 + if(!(daemon->quic_sslctx = quic_sslctx_create( + cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) + fatal_exit("could not set up quic SSL_CTX"); +#endif /* HAVE_NGTCP2 */ } if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, cfg->tls_cert_bundle, cfg->tls_win_cert))) From e82a691efe869187e895b1f5ac4ae345adc754fa Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Tue, 3 Dec 2024 14:21:34 +0100 Subject: [PATCH 11/15] Changelog entry for #1187: - Merge #1187: Create the SSL_CTX for QUIC before chroot and privilege drop. --- doc/Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/Changelog b/doc/Changelog index 5e625dc97..229983346 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -7,6 +7,8 @@ - Merge #1198: Fix log-servfail with serve expired and no useful cache contents. - Safeguard alias loop while looking in the cache for expired answers. + - Merge #1187: Create the SSL_CTX for QUIC before chroot and privilege + drop. 22 November 2024: Yorgos - Fix #1175: serve-expired does not adhere to secure-by-default From ded4c82ced83f12f0498eed40a815c11a5e6848b Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Tue, 3 Dec 2024 16:03:05 +0100 Subject: [PATCH 12/15] - Fix typo in log_servfail.tdir test. --- doc/Changelog | 1 + testdata/log_servfail.tdir/log_servfail.test | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/Changelog b/doc/Changelog index 229983346..534f2e973 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -9,6 +9,7 @@ - Safeguard alias loop while looking in the cache for expired answers. - Merge #1187: Create the SSL_CTX for QUIC before chroot and privilege drop. + - Fix typo in log_servfail.tdir test. 22 November 2024: Yorgos - Fix #1175: serve-expired does not adhere to secure-by-default diff --git a/testdata/log_servfail.tdir/log_servfail.test b/testdata/log_servfail.tdir/log_servfail.test index a6156ba04..1d19e5ca3 100644 --- a/testdata/log_servfail.tdir/log_servfail.test +++ b/testdata/log_servfail.tdir/log_servfail.test @@ -1,4 +1,4 @@ -# #-- cookie_file.test --# +# #-- log_servfail.test --# # source the master var file when it's there [ -f ../.tpkg.var.master ] && source ../.tpkg.var.master # use .tpkg.var.test for in test variable passing From eb08dc617a52e1c3e28300ac6cc2de74edfb6146 Mon Sep 17 00:00:00 2001 From: Maarten Aertsen Date: Fri, 13 Dec 2024 13:12:03 +0100 Subject: [PATCH 13/15] set persist-credentials: false per zizmor suggestion --- .github/workflows/analysis_ports.yml | 1 + .github/workflows/ci.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/analysis_ports.yml b/.github/workflows/analysis_ports.yml index 0388e3cca..85b723912 100644 --- a/.github/workflows/analysis_ports.yml +++ b/.github/workflows/analysis_ports.yml @@ -193,6 +193,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: false + persist-credentials: false - name: test_windows if: ${{ matrix.test_windows == 'yes' }} shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f01ed3273..6ca3bc414 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: configure run: ./configure --enable-debug - name: make From 71d821fde9a583204a955f89ba1329954b13902f Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Fri, 13 Dec 2024 13:43:29 +0100 Subject: [PATCH 14/15] Changelog entry for #1204: - Merge #1204: ci: set persist-credentials: false for actions/checkout per zizmor suggestion. --- doc/Changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/Changelog b/doc/Changelog index 534f2e973..d30035743 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +13 December 2024: Yorgos + - Merge #1204: ci: set persist-credentials: false for actions/checkout + per zizmor suggestion. + 3 December 2024: Yorgos - Merge #1189: Fix the dname_str method to cause conversion errors when the domain name length is 255. From e57e537c85ddf5c175b8e785e34cc21c85ec1168 Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Fri, 20 Dec 2024 15:04:34 +0100 Subject: [PATCH 15/15] - For #1207: [FR] Support for RESINFO RRType 261 (RFC9606), add LDNS_RR_TYPE_RESINFO similar to LDNS_RR_TYPE_TXT. --- doc/Changelog | 4 ++++ sldns/rrdef.c | 6 ++++++ sldns/rrdef.h | 2 ++ 3 files changed, 12 insertions(+) diff --git a/doc/Changelog b/doc/Changelog index d30035743..8b2468d46 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +20 December 2024: Yorgos + - For #1207: [FR] Support for RESINFO RRType 261 (RFC9606), add + LDNS_RR_TYPE_RESINFO similar to LDNS_RR_TYPE_TXT. + 13 December 2024: Yorgos - Merge #1204: ci: set persist-credentials: false for actions/checkout per zizmor suggestion. diff --git a/sldns/rrdef.c b/sldns/rrdef.c index e81ebb1fc..9b4d50f44 100644 --- a/sldns/rrdef.c +++ b/sldns/rrdef.c @@ -617,6 +617,12 @@ static sldns_rr_descriptor rdata_field_descriptors[] = { {(enum sldns_enum_rr_type)0, "TYPE258", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }, #endif +{(enum sldns_enum_rr_type)0, "TYPE259", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }, +{(enum sldns_enum_rr_type)0, "TYPE260", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }, + + /* 261 */ + {LDNS_RR_TYPE_RESINFO, "RESINFO", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 }, + /* split in array, no longer contiguous */ #ifdef DRAFT_RRTYPES diff --git a/sldns/rrdef.h b/sldns/rrdef.h index 7cadf7beb..5c6074819 100644 --- a/sldns/rrdef.h +++ b/sldns/rrdef.h @@ -229,6 +229,8 @@ enum sldns_enum_rr_type LDNS_RR_TYPE_CAA = 257, /* RFC 6844 */ LDNS_RR_TYPE_AVC = 258, + LDNS_RR_TYPE_RESINFO = 261, /* RFC 9606 */ + /** DNSSEC Trust Authorities */ LDNS_RR_TYPE_TA = 32768, /* RFC 4431, 5074, DNSSEC Lookaside Validation */