From c4c3b84c448b362a89388520d59d81dc036c4f33 Mon Sep 17 00:00:00 2001 From: Matthew Almond Date: Mar 19 2021 20:03:45 +0000 Subject: Simple bump of unbound to 1.13.1 The goal here is test the PR workflow, not actually tag/deploy this. One of the outstanding questions is if other packages that have a build time dependency on this get rebuilt too. --- diff --git a/.gitignore b/.gitignore index 4fa6c09..91e53cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/unbound-1.7.3.tar.gz +SOURCES/unbound-1.13.1.tar.gz diff --git a/.unbound.metadata b/.unbound.metadata index 4552023..18eae4c 100644 --- a/.unbound.metadata +++ b/.unbound.metadata @@ -1 +1 @@ -106789bdca173d033d769c67be3441b47611612a SOURCES/unbound-1.7.3.tar.gz +561522b06943f6d1c33bd78132db1f7020fc4fd1 SOURCES/unbound-1.13.1.tar.gz diff --git a/SOURCES/unbound-1.7.2-python3-devel.patch b/SOURCES/unbound-1.7.2-python3-devel.patch deleted file mode 100644 index db6fce0..0000000 --- a/SOURCES/unbound-1.7.2-python3-devel.patch +++ /dev/null @@ -1,320 +0,0 @@ -From b5aab36d41f374eddb0f66f28f251588f53a1e1e Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Wed, 27 Jun 2018 05:46:36 +0000 -Subject: [PATCH 1/2] - #4109: Fix that package config depends on python - unconditionally. - -git-svn-id: file:///svn/unbound/trunk@4757 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - configure | 257 +++++++++++++++++++++++++++++++---------------------------- - configure.ac | 5 +- - 2 files changed, 137 insertions(+), 125 deletions(-) - -diff --git a/configure b/configure -index 3f1c372a..2a1687ae 100755 ---- a/configure -+++ b/configure -@@ -670,9 +670,6 @@ SYSTEMD_DAEMON_LIBS - SYSTEMD_DAEMON_CFLAGS - SYSTEMD_LIBS - SYSTEMD_CFLAGS --PKG_CONFIG_LIBDIR --PKG_CONFIG_PATH --PKG_CONFIG - staticexe - PC_LIBEVENT_DEPENDENCY - UNBOUND_EVENT_UNINSTALL -@@ -697,6 +694,9 @@ swig - SWIG_LIB - SWIG - PC_PY_DEPENDENCY -+PKG_CONFIG_LIBDIR -+PKG_CONFIG_PATH -+PKG_CONFIG - PY_MAJOR_VERSION - PYTHON_SITE_PKG - PYTHON_LDFLAGS -@@ -16930,7 +16930,136 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h - CPPFLAGS="$PYTHON_CPPFLAGS" - fi - ub_have_python=yes -- PC_PY_DEPENDENCY="python" -+ -+ -+ -+ -+ -+ -+ -+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then -+ if test -n "$ac_tool_prefix"; then -+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if ${ac_cv_path_PKG_CONFIG+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ case $PKG_CONFIG in -+ [\\/]* | ?:[\\/]*) -+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. -+ ;; -+ *) -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+ ;; -+esac -+fi -+PKG_CONFIG=$ac_cv_path_PKG_CONFIG -+if test -n "$PKG_CONFIG"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -+$as_echo "$PKG_CONFIG" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ -+fi -+if test -z "$ac_cv_path_PKG_CONFIG"; then -+ ac_pt_PKG_CONFIG=$PKG_CONFIG -+ # Extract the first word of "pkg-config", so it can be a program name with args. -+set dummy pkg-config; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ case $ac_pt_PKG_CONFIG in -+ [\\/]* | ?:[\\/]*) -+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. -+ ;; -+ *) -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+ ;; -+esac -+fi -+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -+if test -n "$ac_pt_PKG_CONFIG"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -+$as_echo "$ac_pt_PKG_CONFIG" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ if test "x$ac_pt_PKG_CONFIG" = x; then -+ PKG_CONFIG="" -+ else -+ case $cross_compiling:$ac_tool_warned in -+yes:) -+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -+ac_tool_warned=yes ;; -+esac -+ PKG_CONFIG=$ac_pt_PKG_CONFIG -+ fi -+else -+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -+fi -+ -+fi -+if test -n "$PKG_CONFIG"; then -+ _pkg_min_version=0.9.0 -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } -+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ PKG_CONFIG="" -+ fi -+fi -+ if test -n "$PKG_CONFIG" && \ -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors ""python${PY_MAJOR_VERSION}"") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}" -+else -+ PC_PY_DEPENDENCY="python" -+fi - - - # Check for SWIG -@@ -18960,126 +19089,6 @@ else - fi - - have_systemd=no -- -- -- -- -- -- -- --if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then -- if test -n "$ac_tool_prefix"; then -- # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. --set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_path_PKG_CONFIG+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- case $PKG_CONFIG in -- [\\/]* | ?:[\\/]*) -- ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. -- ;; -- *) -- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- -- ;; --esac --fi --PKG_CONFIG=$ac_cv_path_PKG_CONFIG --if test -n "$PKG_CONFIG"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 --$as_echo "$PKG_CONFIG" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- --fi --if test -z "$ac_cv_path_PKG_CONFIG"; then -- ac_pt_PKG_CONFIG=$PKG_CONFIG -- # Extract the first word of "pkg-config", so it can be a program name with args. --set dummy pkg-config; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- case $ac_pt_PKG_CONFIG in -- [\\/]* | ?:[\\/]*) -- ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. -- ;; -- *) -- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- -- ;; --esac --fi --ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG --if test -n "$ac_pt_PKG_CONFIG"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 --$as_echo "$ac_pt_PKG_CONFIG" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- if test "x$ac_pt_PKG_CONFIG" = x; then -- PKG_CONFIG="" -- else -- case $cross_compiling:$ac_tool_warned in --yes:) --{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 --$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} --ac_tool_warned=yes ;; --esac -- PKG_CONFIG=$ac_pt_PKG_CONFIG -- fi --else -- PKG_CONFIG="$ac_cv_path_PKG_CONFIG" --fi -- --fi --if test -n "$PKG_CONFIG"; then -- _pkg_min_version=0.9.0 -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 --$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } -- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 --$as_echo "yes" >&6; } -- else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } -- PKG_CONFIG="" -- fi --fi - if test "x$enable_systemd" != xno; then : - - -diff --git a/configure.ac b/configure.ac -index 1828253c..b2c95d1a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -586,7 +586,10 @@ if test x_$ub_test_python != x_no; then - CPPFLAGS="$PYTHON_CPPFLAGS" - fi - ub_have_python=yes -- PC_PY_DEPENDENCY="python" -+ PKG_PROG_PKG_CONFIG -+ PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"], -+ [PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"], -+ [PC_PY_DEPENDENCY="python"]) - AC_SUBST(PC_PY_DEPENDENCY) - - # Check for SWIG --- -2.14.4 - diff --git a/SOURCES/unbound-1.7.2-python3-pkgconfig.patch b/SOURCES/unbound-1.7.2-python3-pkgconfig.patch deleted file mode 100644 index 86ba0b8..0000000 --- a/SOURCES/unbound-1.7.2-python3-pkgconfig.patch +++ /dev/null @@ -1,31 +0,0 @@ -From bca54a8b252d4a75e940424dc761c6a4e487eb84 Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Wed, 27 Jun 2018 06:07:31 +0000 -Subject: [PATCH 2/2] =?UTF-8?q?-=20Patch,=20do=20not=20export=20python=20f?= - =?UTF-8?q?rom=20pkg-config,=20from=20Petr=20Men=C5=A1=C3=ADk.?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -git-svn-id: file:///svn/unbound/trunk@4758 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - contrib/libunbound.pc.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/contrib/libunbound.pc.in b/contrib/libunbound.pc.in -index 0cb9f875..810c5713 100644 ---- a/contrib/libunbound.pc.in -+++ b/contrib/libunbound.pc.in -@@ -7,7 +7,8 @@ Name: unbound - Description: Library with validating, recursive, and caching DNS resolver - URL: http://www.unbound.net - Version: @PACKAGE_VERSION@ --Requires: @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@ -+Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@ -+Requires.private: @PC_PY_DEPENDENCY@ - Libs: -L${libdir} -lunbound -lssl -lcrypto - Libs.private: @SSLLIB@ @LIBS@ - Cflags: -I${includedir} --- -2.14.4 - diff --git a/SOURCES/unbound-1.7.3-DNS-over-TLS-memory-leak.patch b/SOURCES/unbound-1.7.3-DNS-over-TLS-memory-leak.patch deleted file mode 100644 index 9823850..0000000 --- a/SOURCES/unbound-1.7.3-DNS-over-TLS-memory-leak.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 377d5b426a30fc915cf7905786f93c0ec89845b7 Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Tue, 25 Sep 2018 09:01:13 +0000 -Subject: [PATCH] - Add SSL cleanup for tcp timeout. - -git-svn-id: file:///svn/unbound/trunk@4915 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - services/outside_network.c | 11 +++++++++++ - 1 files changed, 9 insertions(+) -diff --git a/services/outside_network.c b/services/outside_network.c -index 5700ef8..b52cdab 100644 ---- a/services/outside_network.c -+++ b/services/outside_network.c -@@ -373,6 +373,8 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) - if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) { - log_err("SSL_set1_host failed"); - pend->c->fd = s; -+ SSL_free(pend->c->ssl); -+ pend->c->ssl = NULL; - comm_point_close(pend->c); - return 0; - } -@@ -1258,6 +1260,13 @@ outnet_tcptimer(void* arg) - } else { - /* it was in use */ - struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting; -+ if(pend->c->ssl) { -+#ifdef HAVE_SSL -+ SSL_shutdown(pend->c->ssl); -+ SSL_free(pend->c->ssl); -+ pend->c->ssl = NULL; -+#endif -+ } - comm_point_close(pend->c); - pend->query = NULL; - pend->next_free = outnet->tcp_free; diff --git a/SOURCES/unbound-1.7.3-additional-logging.patch b/SOURCES/unbound-1.7.3-additional-logging.patch deleted file mode 100644 index 7630422..0000000 --- a/SOURCES/unbound-1.7.3-additional-logging.patch +++ /dev/null @@ -1,553 +0,0 @@ -diff --git a/daemon/worker.c b/daemon/worker.c -index 44a989a..3acecc1 100644 ---- a/daemon/worker.c -+++ b/daemon/worker.c -@@ -1193,7 +1193,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, - if(worker->env.cfg->log_queries) { - char ip[128]; - addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); -- log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass); -+ log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass); - } - if(qinfo.qtype == LDNS_RR_TYPE_AXFR || - qinfo.qtype == LDNS_RR_TYPE_IXFR) { -diff --git a/doc/Changelog b/doc/Changelog -index 3d05ae5..bb74461 100644 ---- a/doc/Changelog -+++ b/doc/Changelog -@@ -1,3 +1,15 @@ -+30 November 2018: Wouter -+ - log-tag-queryreply: yes in unbound.conf tags the log-queries and -+ log-replies in the log file for easier log filter maintenance. -+ -+21 August 2018: Wouter -+ - log-local-actions: yes option for unbound.conf that logs all the -+ local zone actions, a patch from Saksham Manchanda (Secure64). -+ -+17 August 2018: Wouter -+ - log-servfail: yes prints log lines that say why queries are -+ returning SERVFAIL to clients. -+ - 19 June 2018: Wouter - - Fix for unbound-control on Windows and set TCP socket parameters - more closely. -diff --git a/doc/example.conf.in b/doc/example.conf.in -index be83bda..aa06cee 100644 ---- a/doc/example.conf.in -+++ b/doc/example.conf.in -@@ -309,6 +309,17 @@ server: - # timetoresolve, fromcache and responsesize. - # log-replies: no - -+ # log with tag 'query' and 'reply' instead of 'info' for -+ # filtering log-queries and log-replies from the log. -+ # log-tag-queryreply: no -+ -+ # log the local-zone actions, like local-zone type inform is enabled -+ # also for the other local zone types. -+ # log-local-actions: no -+ -+ # print log lines that say why queries return SERVFAIL to clients. -+ # log-servfail: no -+ - # the pid file. Can be an absolute path outside of chroot/work dir. - # pidfile: "@UNBOUND_PIDFILE@" - -diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in -index 9167a5a..b73bc70 100644 ---- a/doc/unbound.conf.5.in -+++ b/doc/unbound.conf.5.in -@@ -618,6 +618,21 @@ Default is no. Note that it takes time to print these - lines which makes the server (significantly) slower. Odd (nonprintable) - characters in names are printed as '?'. - .TP -+.B log\-tag\-queryreply: \fI -+Prints the word 'query' and 'reply' with log\-queries and log\-replies. -+This makes filtering logs easier. The default is off (for backwards -+compatibility). -+.TP -+.B log\-local\-actions: \fI -+Print log lines to inform about local zone actions. These lines are like the -+local\-zone type inform prints out, but they are also printed for the other -+types of local zones. -+.TP -+.B log\-servfail: \fI -+Print log lines that say why queries return SERVFAIL to clients. -+This is separate from the verbosity debug logs, much smaller, and printed -+at the error level, not the info level of debug info from verbosity. -+.TP - .B pidfile: \fI - The process id is written to the file. Default is "@UNBOUND_PIDFILE@". - So, -diff --git a/services/localzone.c b/services/localzone.c -index 0f60817..a85619b 100644 ---- a/services/localzone.c -+++ b/services/localzone.c -@@ -1459,7 +1459,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo, - uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); - dname_str(z->name, zname); - addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); -- snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip, -+ snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip, - (unsigned)port); - log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); - } -@@ -1576,7 +1576,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, - z->override_tree, &tag, tagname, num_tags); - lock_rw_unlock(&zones->lock); - } -- if((lzt == local_zone_inform || lzt == local_zone_inform_deny) -+ if((env->cfg->log_local_actions || -+ lzt == local_zone_inform || lzt == local_zone_inform_deny) - && repinfo) - lz_inform_print(z, qinfo, repinfo); - -diff --git a/services/mesh.c b/services/mesh.c -index 41aba74..55c1947 100644 ---- a/services/mesh.c -+++ b/services/mesh.c -@@ -977,7 +977,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, - rcode = LDNS_RCODE_SERVFAIL; - if(!rcode && (rep->security == sec_status_bogus || - rep->security == sec_status_secure_sentinel_fail)) { -- if(!(reason = errinf_to_str(&m->s))) -+ if(!(reason = errinf_to_str_bogus(&m->s))) - rcode = LDNS_RCODE_SERVFAIL; - } - /* send the reply */ -@@ -1148,6 +1148,15 @@ void mesh_query_done(struct mesh_state* mstate) - struct mesh_cb* c; - struct reply_info* rep = (mstate->s.return_msg? - mstate->s.return_msg->rep:NULL); -+ if((mstate->s.return_rcode == LDNS_RCODE_SERVFAIL || -+ (rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL)) -+ && mstate->s.env->cfg->log_servfail -+ && !mstate->s.env->cfg->val_log_squelch) { -+ char* err = errinf_to_str_servfail(&mstate->s); -+ if(err) -+ log_err("%s", err); -+ free(err); -+ } - for(r = mstate->reply_list; r; r = r->next) { - /* if a response-ip address block has been stored the - * information should be logged for each client. */ -diff --git a/util/config_file.c b/util/config_file.c -index b061760..68a0a15 100644 ---- a/util/config_file.c -+++ b/util/config_file.c -@@ -115,6 +115,9 @@ config_create(void) - cfg->log_time_ascii = 0; - cfg->log_queries = 0; - cfg->log_replies = 0; -+ cfg->log_tag_queryreply = 0; -+ cfg->log_local_actions = 0; -+ cfg->log_servfail = 0; - #ifndef USE_WINSOCK - # ifdef USE_MINI_EVENT - /* select max 1024 sockets */ -@@ -540,6 +543,9 @@ int config_set_option(struct config_file* cfg, const char* opt, - else S_YNO("val-log-squelch:", val_log_squelch) - else S_YNO("log-queries:", log_queries) - else S_YNO("log-replies:", log_replies) -+ else S_YNO("log-tag-queryreply:", log_tag_queryreply) -+ else S_YNO("log-local-actions:", log_local_actions) -+ else S_YNO("log-servfail:", log_servfail) - else S_YNO("val-permissive-mode:", val_permissive_mode) - else S_YNO("aggressive-nsec:", aggressive_nsec) - else S_YNO("ignore-cd-flag:", ignore_cd) -@@ -893,6 +899,9 @@ config_get_option(struct config_file* cfg, const char* opt, - else O_STR(opt, "logfile", logfile) - else O_YNO(opt, "log-queries", log_queries) - else O_YNO(opt, "log-replies", log_replies) -+ else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply) -+ else O_YNO(opt, "log-local-actions", log_local_actions) -+ else O_YNO(opt, "log-servfail", log_servfail) - else O_STR(opt, "pidfile", pidfile) - else O_YNO(opt, "hide-identity", hide_identity) - else O_YNO(opt, "hide-version", hide_version) -@@ -1845,6 +1854,7 @@ config_apply(struct config_file* config) - EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size; - MINIMAL_RESPONSES = config->minimal_responses; - RRSET_ROUNDROBIN = config->rrset_roundrobin; -+ LOG_TAG_QUERYREPLY = config->log_tag_queryreply; - log_set_time_asc(config->log_time_ascii); - autr_permit_small_holddown = config->permit_small_holddown; - } -@@ -2220,7 +2230,7 @@ void errinf_origin(struct module_qstate* qstate, struct sock_list *origin) - } - } - --char* errinf_to_str(struct module_qstate* qstate) -+char* errinf_to_str_bogus(struct module_qstate* qstate) - { - char buf[20480]; - char* p = buf; -@@ -2245,6 +2255,31 @@ char* errinf_to_str(struct module_qstate* qstate) - return p; - } - -+char* errinf_to_str_servfail(struct module_qstate* qstate) -+{ -+ char buf[20480]; -+ char* p = buf; -+ size_t left = sizeof(buf); -+ struct config_strlist* s; -+ char dname[LDNS_MAX_DOMAINLEN+1]; -+ 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)); -+ dname_str(qstate->qinfo.qname, dname); -+ snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c); -+ left -= strlen(p); p += strlen(p); -+ if(!qstate->errinf) -+ snprintf(p, left, " misc failure"); -+ else for(s=qstate->errinf; s; s=s->next) { -+ snprintf(p, left, " %s", s->str); -+ left -= strlen(p); p += strlen(p); -+ } -+ p = strdup(buf); -+ if(!p) -+ log_err("malloc failure in errinf_to_str"); -+ return p; -+} -+ - void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) - { - char buf[1024]; -diff --git a/util/config_file.h b/util/config_file.h -index 4206eb9..1e7f402 100644 ---- a/util/config_file.h -+++ b/util/config_file.h -@@ -268,6 +268,12 @@ struct config_file { - int log_queries; - /** log replies with one line per reply */ - int log_replies; -+ /** tag log_queries and log_replies for filtering */ -+ int log_tag_queryreply; -+ /** log every local-zone hit **/ -+ int log_local_actions; -+ /** log servfails with a reason */ -+ int log_servfail; - /** log identity to report */ - char* log_identity; - -@@ -1070,7 +1076,15 @@ void errinf_dname(struct module_qstate* qstate, const char* str, - * @return string or NULL on malloc failure (already logged). - * This string is malloced and has to be freed by caller. - */ --char* errinf_to_str(struct module_qstate* qstate); -+char* errinf_to_str_bogus(struct module_qstate* qstate); -+ -+/** -+ * Create error info in string. For other servfails. -+ * @param qstate: query state. -+ * @return string or NULL on malloc failure (already logged). -+ * This string is malloced and has to be freed by caller. -+ */ -+char* errinf_to_str_servfail(struct module_qstate* qstate); - - /** - * Used during options parsing -diff --git a/util/configlexer.lex b/util/configlexer.lex -index 6124e32..9b22db1 100644 ---- a/util/configlexer.lex -+++ b/util/configlexer.lex -@@ -366,6 +366,9 @@ log-identity{COLON} { YDVAR(1, VAR_LOG_IDENTITY) } - log-time-ascii{COLON} { YDVAR(1, VAR_LOG_TIME_ASCII) } - log-queries{COLON} { YDVAR(1, VAR_LOG_QUERIES) } - log-replies{COLON} { YDVAR(1, VAR_LOG_REPLIES) } -+log-tag-queryreply{COLON} { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) } -+log-local-actions{COLON} { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) } -+log-servfail{COLON} { YDVAR(1, VAR_LOG_SERVFAIL) } - local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) } - local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) } - local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) } -diff --git a/util/configparser.y b/util/configparser.y -index e34665a..4b23a71 100644 ---- a/util/configparser.y -+++ b/util/configparser.y -@@ -106,7 +106,7 @@ extern struct config_parser_state* cfg_parser; - %token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN - %token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH - %token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN --%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES -+%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES VAR_LOG_LOCAL_ACTIONS - %token VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM - %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST - %token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE -@@ -158,6 +158,8 @@ extern struct config_parser_state* cfg_parser; - %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM - %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL - %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT -+%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL -+%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY - - %% - toplevelvars: /* empty */ | toplevelvars toplevelvar ; -@@ -217,6 +219,7 @@ content_server: server_num_threads | server_verbosity | server_port | - server_edns_buffer_size | server_prefetch | server_prefetch_key | - server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag | - server_log_queries | server_log_replies | server_tcp_upstream | server_ssl_upstream | -+ server_log_local_actions | - server_ssl_service_key | server_ssl_service_pem | server_ssl_port | - server_minimal_responses | server_rrset_roundrobin | server_max_udp_size | - server_so_reuseport | server_delay_close | -@@ -249,7 +252,9 @@ content_server: server_num_threads | server_verbosity | server_port | - server_ipsecmod_whitelist | server_ipsecmod_strict | - server_udp_upstream_without_downstream | server_aggressive_nsec | - server_tls_cert_bundle | server_tls_additional_port | server_low_rtt | -- server_low_rtt_permil | server_tls_win_cert -+ server_low_rtt_permil | server_tls_win_cert | -+ server_tcp_connection_limit | server_log_servfail | -+ server_unknown_server_time_limit | server_log_tag_queryreply - ; - stubstart: VAR_STUB_ZONE - { -@@ -764,6 +769,33 @@ server_log_replies: VAR_LOG_REPLIES STRING_ARG - free($2); - } - ; -+server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG -+ { -+ OUTYY(("P(server_log_tag_queryreply:%s)\n", $2)); -+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) -+ yyerror("expected yes or no."); -+ else cfg_parser->cfg->log_tag_queryreply = (strcmp($2, "yes")==0); -+ free($2); -+ } -+ ; -+server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG -+ { -+ OUTYY(("P(server_log_servfail:%s)\n", $2)); -+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) -+ yyerror("expected yes or no."); -+ else cfg_parser->cfg->log_servfail = (strcmp($2, "yes")==0); -+ free($2); -+ } -+ ; -+server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG -+ { -+ OUTYY(("P(server_log_local_actions:%s)\n", $2)); -+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) -+ yyerror("expected yes or no."); -+ else cfg_parser->cfg->log_local_actions = (strcmp($2, "yes")==0); -+ free($2); -+ } -+ ; - server_chroot: VAR_CHROOT STRING_ARG - { - OUTYY(("P(server_chroot:%s)\n", $2)); -diff --git a/util/data/msgreply.c b/util/data/msgreply.c -index 772f5d1..df2131c 100644 ---- a/util/data/msgreply.c -+++ b/util/data/msgreply.c -@@ -844,7 +844,9 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, - addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf)); - if(rcode == LDNS_RCODE_FORMERR) - { -- log_info("%s - - - %s - - - ", clientip_buf, rcode_buf); -+ if(LOG_TAG_QUERYREPLY) -+ log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf); -+ else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf); - } else { - if(qinf->qname) - dname_str(qinf->qname, qname_buf); -@@ -852,7 +854,11 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, - pktlen = sldns_buffer_limit(rmsg); - sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf)); - sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf)); -- log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d", -+ if(LOG_TAG_QUERYREPLY) -+ log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d", -+ clientip_buf, qname_buf, type_buf, class_buf, -+ rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen); -+ else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d", - clientip_buf, qname_buf, type_buf, class_buf, - rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen); - } -diff --git a/util/log.c b/util/log.c -index 43dd572..fff4319 100644 ---- a/util/log.c -+++ b/util/log.c -@@ -391,6 +391,24 @@ log_hex(const char* msg, void* data, size_t length) - log_hex_f(verbosity, msg, data, length); - } - -+void -+log_query(const char *format, ...) -+{ -+ va_list args; -+ va_start(args, format); -+ log_vmsg(LOG_INFO, "query", format, args); -+ va_end(args); -+} -+ -+void -+log_reply(const char *format, ...) -+{ -+ va_list args; -+ va_start(args, format); -+ log_vmsg(LOG_INFO, "reply", format, args); -+ va_end(args); -+} -+ - void log_buf(enum verbosity_value level, const char* msg, sldns_buffer* buf) - { - if(verbosity < level) -diff --git a/util/log.h b/util/log.h -index 7bc3d9e..172cd01 100644 ---- a/util/log.h -+++ b/util/log.h -@@ -160,6 +160,20 @@ void log_warn(const char* format, ...) ATTR_FORMAT(printf, 1, 2); - */ - void log_hex(const char* msg, void* data, size_t length); - -+/** -+ * Log query. -+ * Pass printf formatted arguments. No trailing newline is needed. -+ * @param format: printf-style format string. Arguments follow. -+ */ -+void log_query(const char* format, ...) ATTR_FORMAT(printf, 1, 2); -+ -+/** -+ * Log reply. -+ * Pass printf formatted arguments. No trailing newline is needed. -+ * @param format: printf-style format string. Arguments follow. -+ */ -+void log_reply(const char* format, ...) ATTR_FORMAT(printf, 1, 2); -+ - /** - * Easy alternative for log_hex, takes a sldns_buffer. - * @param level: verbosity level for this message, compared to global -diff --git a/util/net_help.c b/util/net_help.c -index a193c36..617a896 100644 ---- a/util/net_help.c -+++ b/util/net_help.c -@@ -67,6 +67,9 @@ int MINIMAL_RESPONSES = 0; - /** rrset order roundrobin: default is no */ - int RRSET_ROUNDROBIN = 0; - -+/** log tag queries with name instead of 'info' for filtering */ -+int LOG_TAG_QUERYREPLY = 0; -+ - /* returns true is string addr is an ip6 specced address */ - int - str_is_ip6(const char* str) -@@ -335,7 +338,7 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, - { - char buf[LDNS_MAX_DOMAINLEN+1]; - char t[12], c[12]; -- const char *ts, *cs; -+ const char *ts, *cs; - if(verbosity < v) - return; - dname_str(name, buf); -@@ -361,6 +364,37 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, - log_info("%s %s %s %s", str, buf, ts, cs); - } - -+void -+log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass) -+{ -+ char buf[LDNS_MAX_DOMAINLEN+1]; -+ char t[12], c[12]; -+ const char *ts, *cs; -+ dname_str(name, buf); -+ if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG"; -+ else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR"; -+ else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR"; -+ else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB"; -+ else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA"; -+ else if(type == LDNS_RR_TYPE_ANY) ts = "ANY"; -+ else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name) -+ ts = sldns_rr_descript(type)->_name; -+ else { -+ snprintf(t, sizeof(t), "TYPE%d", (int)type); -+ ts = t; -+ } -+ if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) && -+ sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name) -+ cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name; -+ else { -+ snprintf(c, sizeof(c), "CLASS%d", (int)dclass); -+ cs = c; -+ } -+ if(LOG_TAG_QUERYREPLY) -+ log_query("%s %s %s %s", str, buf, ts, cs); -+ else log_info("%s %s %s %s", str, buf, ts, cs); -+} -+ - void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, - struct sockaddr_storage* addr, socklen_t addrlen) - { -diff --git a/util/net_help.h b/util/net_help.h -index de2e1ac..f2e0e43 100644 ---- a/util/net_help.h -+++ b/util/net_help.h -@@ -99,6 +99,9 @@ extern int MINIMAL_RESPONSES; - /** rrset order roundrobin */ - extern int RRSET_ROUNDROBIN; - -+/** log tag queries with name instead of 'info' for filtering */ -+extern int LOG_TAG_QUERYREPLY; -+ - /** - * See if string is ip4 or ip6. - * @param str: IP specification. -@@ -235,6 +238,12 @@ void sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, - void log_nametypeclass(enum verbosity_value v, const char* str, - uint8_t* name, uint16_t type, uint16_t dclass); - -+/** -+ * Like log_nametypeclass, but logs with log_query for query logging -+ */ -+void log_query_in(const char* str, uint8_t* name, uint16_t type, -+ uint16_t dclass); -+ - /** - * Compare two sockaddrs. Imposes an ordering on the addresses. - * Compares address and port. -diff --git a/validator/val_kcache.c b/validator/val_kcache.c -index 22070cc..e0b88b6 100644 ---- a/validator/val_kcache.c -+++ b/validator/val_kcache.c -@@ -89,7 +89,7 @@ key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey, - if(key_entry_isbad(k) && qstate->errinf && - qstate->env->cfg->val_log_level >= 2) { - /* on malloc failure there is simply no reason string */ -- key_entry_set_reason(k, errinf_to_str(qstate)); -+ key_entry_set_reason(k, errinf_to_str_bogus(qstate)); - } - key_entry_hash(k); - slabhash_insert(kcache->slab, k->entry.hash, &k->entry, -diff --git a/validator/validator.c b/validator/validator.c -index 5777b29..2d9cc17 100644 ---- a/validator/validator.c -+++ b/validator/validator.c -@@ -2227,13 +2227,15 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, - vq->orig_msg->rep->ttl = ve->bogus_ttl; - vq->orig_msg->rep->prefetch_ttl = - PREFETCH_TTL_CALC(vq->orig_msg->rep->ttl); -- if(qstate->env->cfg->val_log_level >= 1 && -+ if((qstate->env->cfg->val_log_level >= 1 || -+ qstate->env->cfg->log_servfail) && - !qstate->env->cfg->val_log_squelch) { -- if(qstate->env->cfg->val_log_level < 2) -+ if(qstate->env->cfg->val_log_level < 2 && -+ !qstate->env->cfg->log_servfail) - log_query_info(0, "validation failure", - &qstate->qinfo); - else { -- char* err = errinf_to_str(qstate); -+ char* err = errinf_to_str_bogus(qstate); - if(err) log_info("%s", err); - free(err); - } -@@ -2332,6 +2334,7 @@ processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq, - - if(vq->dlv_status == dlv_error) { - verbose(VERB_QUERY, "failed DLV lookup"); -+ errinf(qstate, "failed DLV lookup"); - return val_error(qstate, id); - } else if(vq->dlv_status == dlv_success) { - uint8_t* nm; diff --git a/SOURCES/unbound-1.7.3-amplifying-an-incoming-query.patch b/SOURCES/unbound-1.7.3-amplifying-an-incoming-query.patch deleted file mode 100644 index a3f9aef..0000000 --- a/SOURCES/unbound-1.7.3-amplifying-an-incoming-query.patch +++ /dev/null @@ -1,944 +0,0 @@ -diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c -index f88b3e1..522e0e9 100644 ---- a/iterator/iter_delegpt.c -+++ b/iterator/iter_delegpt.c -@@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region) - } - for(a = dp->target_list; a; a = a->next_target) { - if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, -- a->bogus, a->lame, a->tls_auth_name)) -+ a->bogus, a->lame, a->tls_auth_name, NULL)) - return NULL; - } - return copy; -@@ -161,7 +161,7 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr, - int - delegpt_add_target(struct delegpt* dp, struct regional* region, - uint8_t* name, size_t namelen, struct sockaddr_storage* addr, -- socklen_t addrlen, uint8_t bogus, uint8_t lame) -+ socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions) - { - struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); - log_assert(!dp->dp_type_mlc); -@@ -176,13 +176,14 @@ delegpt_add_target(struct delegpt* dp, struct regional* region, - if(ns->got4 && ns->got6) - ns->resolved = 1; - } -- return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL); -+ return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL, -+ additions); - } - - int - delegpt_add_addr(struct delegpt* dp, struct regional* region, - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, -- uint8_t lame, char* tls_auth_name) -+ uint8_t lame, char* tls_auth_name, int* additions) - { - struct delegpt_addr* a; - log_assert(!dp->dp_type_mlc); -@@ -195,6 +196,9 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region, - return 1; - } - -+ if(additions) -+ *additions = 1; -+ - a = (struct delegpt_addr*)regional_alloc(region, - sizeof(struct delegpt_addr)); - if(!a) -@@ -382,10 +386,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region) - continue; - - if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) { -- if(!delegpt_add_rrset_A(dp, region, s, 0)) -+ if(!delegpt_add_rrset_A(dp, region, s, 0, NULL)) - return NULL; - } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) { -- if(!delegpt_add_rrset_AAAA(dp, region, s, 0)) -+ if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL)) - return NULL; - } - } -@@ -416,7 +420,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region, - - int - delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, -- struct ub_packed_rrset_key* ak, uint8_t lame) -+ struct ub_packed_rrset_key* ak, uint8_t lame, int* additions) - { - struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; - size_t i; -@@ -432,7 +436,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, - memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE); - if(!delegpt_add_target(dp, region, ak->rk.dname, - ak->rk.dname_len, (struct sockaddr_storage*)&sa, -- len, (d->security==sec_status_bogus), lame)) -+ len, (d->security==sec_status_bogus), lame, additions)) - return 0; - } - return 1; -@@ -440,7 +444,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, - - int - delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, -- struct ub_packed_rrset_key* ak, uint8_t lame) -+ struct ub_packed_rrset_key* ak, uint8_t lame, int* additions) - { - struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; - size_t i; -@@ -456,7 +460,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, - memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE); - if(!delegpt_add_target(dp, region, ak->rk.dname, - ak->rk.dname_len, (struct sockaddr_storage*)&sa, -- len, (d->security==sec_status_bogus), lame)) -+ len, (d->security==sec_status_bogus), lame, additions)) - return 0; - } - return 1; -@@ -464,20 +468,32 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, - - int - delegpt_add_rrset(struct delegpt* dp, struct regional* region, -- struct ub_packed_rrset_key* rrset, uint8_t lame) -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions) - { - if(!rrset) - return 1; - if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS) - return delegpt_rrset_add_ns(dp, region, rrset, lame); - else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A) -- return delegpt_add_rrset_A(dp, region, rrset, lame); -+ return delegpt_add_rrset_A(dp, region, rrset, lame, additions); - else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA) -- return delegpt_add_rrset_AAAA(dp, region, rrset, lame); -+ return delegpt_add_rrset_AAAA(dp, region, rrset, lame, additions); - log_warn("Unknown rrset type added to delegpt"); - return 1; - } - -+void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype) -+{ -+ if(ns) { -+ if(qtype == LDNS_RR_TYPE_A) -+ ns->got4 = 2; -+ else if(qtype == LDNS_RR_TYPE_AAAA) -+ ns->got6 = 2; -+ if(ns->got4 && ns->got6) -+ ns->resolved = 1; -+ } -+} -+ - void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg) - { - struct reply_info* rep = (struct reply_info*)msg->entry.data; -@@ -487,14 +503,7 @@ void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg) - if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) { - struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, - msg->key.qname_len); -- if(ns) { -- if(msg->key.qtype == LDNS_RR_TYPE_A) -- ns->got4 = 1; -- else if(msg->key.qtype == LDNS_RR_TYPE_AAAA) -- ns->got6 = 1; -- if(ns->got4 && ns->got6) -- ns->resolved = 1; -- } -+ delegpt_mark_neg(ns, msg->key.qtype); - } - } - -diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h -index 354bd61..3aded22 100644 ---- a/iterator/iter_delegpt.h -+++ b/iterator/iter_delegpt.h -@@ -104,9 +104,10 @@ struct delegpt_ns { - * and marked true if got4 and got6 are both true. - */ - int resolved; -- /** if the ipv4 address is in the delegpt */ -+ /** if the ipv4 address is in the delegpt, 0=not, 1=yes 2=negative, -+ * negative means it was done, but no content. */ - uint8_t got4; -- /** if the ipv6 address is in the delegpt */ -+ /** if the ipv6 address is in the delegpt, 0=not, 1=yes 2=negative */ - uint8_t got6; - /** - * If the name is parent-side only and thus dispreferred. -@@ -213,11 +214,12 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional, - * @param addrlen: the length of addr. - * @param bogus: security status for the address, pass true if bogus. - * @param lame: address is lame. -+ * @param additions: will be set to 1 if a new address is added - * @return false on error. - */ - int delegpt_add_target(struct delegpt* dp, struct regional* regional, - uint8_t* name, size_t namelen, struct sockaddr_storage* addr, -- socklen_t addrlen, uint8_t bogus, uint8_t lame); -+ socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions); - - /** - * Add A RRset to delegpt. -@@ -225,10 +227,11 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional, - * @param regional: where to allocate the info. - * @param rrset: RRset A to add. - * @param lame: rrset is lame, disprefer it. -+ * @param additions: will be set to 1 if a new address is added - * @return 0 on alloc error. - */ - int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional, -- struct ub_packed_rrset_key* rrset, uint8_t lame); -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions); - - /** - * Add AAAA RRset to delegpt. -@@ -236,10 +239,11 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional, - * @param regional: where to allocate the info. - * @param rrset: RRset AAAA to add. - * @param lame: rrset is lame, disprefer it. -+ * @param additions: will be set to 1 if a new address is added - * @return 0 on alloc error. - */ - int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional, -- struct ub_packed_rrset_key* rrset, uint8_t lame); -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions); - - /** - * Add any RRset to delegpt. -@@ -248,10 +252,11 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional, - * @param regional: where to allocate the info. - * @param rrset: RRset to add, NS, A, AAAA. - * @param lame: rrset is lame, disprefer it. -+ * @param additions: will be set to 1 if a new address is added - * @return 0 on alloc error. - */ - int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, -- struct ub_packed_rrset_key* rrset, uint8_t lame); -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions); - - /** - * Add address to the delegation point. No servername is associated or checked. -@@ -262,11 +267,13 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, - * @param bogus: if address is bogus. - * @param lame: if address is lame. - * @param tls_auth_name: TLS authentication name (or NULL). -+ * @param additions: will be set to 1 if a new address is added -+ * @return 0 on alloc error. - * @return false on error. - */ - int delegpt_add_addr(struct delegpt* dp, struct regional* regional, - struct sockaddr_storage* addr, socklen_t addrlen, -- uint8_t bogus, uint8_t lame, char* tls_auth_name); -+ uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions); - - /** - * Find NS record in name list of delegation point. -@@ -339,6 +346,14 @@ size_t delegpt_count_targets(struct delegpt* dp); - struct delegpt* delegpt_from_message(struct dns_msg* msg, - struct regional* regional); - -+/** -+* Mark negative return in delegation point for specific nameserver. -+* sets the got4 or got6 to negative, updates the ns->resolved. -+* @param ns: the nameserver in the delegpt. -+* @param qtype: A or AAAA (host order). -+*/ -+void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype); -+ - /** - * Add negative message to delegation point. - * @param dp: delegation point. -diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c -index 12580dc..8230d17 100644 ---- a/iterator/iter_scrub.c -+++ b/iterator/iter_scrub.c -@@ -185,8 +185,9 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg, - /** Get target name of a CNAME */ - static int - parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, -- size_t* snamelen) -+ size_t* snamelen, sldns_buffer* pkt) - { -+ size_t oldpos, dlen; - if(rrset->rr_count != 1) { - struct rr_parse* sig; - verbose(VERB_ALGO, "Found CNAME rrset with " -@@ -204,6 +205,19 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, - *sname = rrset->rr_first->ttl_data + sizeof(uint32_t) - + sizeof(uint16_t); /* skip ttl, rdatalen */ - *snamelen = rrset->rr_first->size - sizeof(uint16_t); -+ -+ if(rrset->rr_first->outside_packet) { -+ if(!dname_valid(*sname, *snamelen)) -+ return 0; -+ return 1; -+ } -+ oldpos = sldns_buffer_position(pkt); -+ sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt))); -+ dlen = pkt_dname_len(pkt); -+ sldns_buffer_set_position(pkt, oldpos); -+ if(dlen == 0) -+ return 0; /* parse fail on the rdata name */ -+ *snamelen = dlen; - return 1; - } - -@@ -215,7 +229,7 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset, - /* we already know that sname is a strict subdomain of DNAME owner */ - uint8_t* dtarg = NULL; - size_t dtarglen; -- if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen)) -+ if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt)) - return 0; - log_assert(qnamelen > dname_rrset->dname_len); - /* DNAME from com. to net. with qname example.com. -> example.net. */ -@@ -372,7 +386,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, - /* check next cname */ - uint8_t* t = NULL; - size_t tlen = 0; -- if(!parse_get_cname_target(nx, &t, &tlen)) -+ if(!parse_get_cname_target(nx, &t, &tlen, pkt)) - return 0; - if(dname_pkt_compare(pkt, alias, t) == 0) { - /* it's OK and better capitalized */ -@@ -423,7 +437,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, - size_t tlen = 0; - if(synth_cname(sname, snamelen, nx, alias, - &aliaslen, pkt) && -- parse_get_cname_target(rrset, &t, &tlen) && -+ parse_get_cname_target(rrset, &t, &tlen, pkt) && - dname_pkt_compare(pkt, alias, t) == 0) { - /* the synthesized CNAME equals the - * current CNAME. This CNAME is the -@@ -442,7 +456,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, - } - - /* move to next name in CNAME chain */ -- if(!parse_get_cname_target(rrset, &sname, &snamelen)) -+ if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt)) - return 0; - prev = rrset; - rrset = rrset->rrset_all_next; -diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c -index 0a8f770..a107bee 100644 ---- a/iterator/iter_utils.c -+++ b/iterator/iter_utils.c -@@ -1008,7 +1008,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env, - log_rrset_key(VERB_ALGO, "found parent-side", akey); - ns->done_pside4 = 1; - /* a negative-cache-element has no addresses it adds */ -- if(!delegpt_add_rrset_A(dp, region, akey, 1)) -+ if(!delegpt_add_rrset_A(dp, region, akey, 1, NULL)) - log_err("malloc failure in lookup_parent_glue"); - lock_rw_unlock(&akey->entry.lock); - } -@@ -1020,7 +1020,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env, - log_rrset_key(VERB_ALGO, "found parent-side", akey); - ns->done_pside6 = 1; - /* a negative-cache-element has no addresses it adds */ -- if(!delegpt_add_rrset_AAAA(dp, region, akey, 1)) -+ if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, NULL)) - log_err("malloc failure in lookup_parent_glue"); - lock_rw_unlock(&akey->entry.lock); - } -diff --git a/iterator/iterator.c b/iterator/iterator.c -index 58a9bff..a4ad319 100644 ---- a/iterator/iterator.c -+++ b/iterator/iterator.c -@@ -69,6 +69,8 @@ - #include "sldns/parseutil.h" - #include "sldns/sbuffer.h" - -+static void target_count_increase_nx(struct iter_qstate* iq, int num); -+ - int - iter_init(struct module_env* env, int id) - { -@@ -147,6 +149,7 @@ iter_new(struct module_qstate* qstate, int id) - iq->sent_count = 0; - iq->ratelimit_ok = 0; - iq->target_count = NULL; -+ iq->dp_target_count = 0; - iq->wait_priming_stub = 0; - iq->refetch_glue = 0; - iq->dnssec_expected = 0; -@@ -218,6 +221,7 @@ final_state(struct iter_qstate* iq) - static void - error_supers(struct module_qstate* qstate, int id, struct module_qstate* super) - { -+ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; - struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id]; - - if(qstate->qinfo.qtype == LDNS_RR_TYPE_A || -@@ -242,7 +246,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super) - super->region, super_iq->dp)) - log_err("out of memory adding missing"); - } -+ delegpt_mark_neg(dpns, qstate->qinfo.qtype); - dpns->resolved = 1; /* mark as failed */ -+ if((dpns->got4 == 2 || !ie->supports_ipv4) && -+ (dpns->got6 == 2 || !ie->supports_ipv6)) -+ target_count_increase_nx(super_iq, 1); - } - if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) { - /* prime failed to get delegation */ -@@ -577,7 +585,7 @@ static void - target_count_create(struct iter_qstate* iq) - { - if(!iq->target_count) { -- iq->target_count = (int*)calloc(2, sizeof(int)); -+ iq->target_count = (int*)calloc(3, sizeof(int)); - /* if calloc fails we simply do not track this number */ - if(iq->target_count) - iq->target_count[0] = 1; -@@ -590,6 +598,15 @@ target_count_increase(struct iter_qstate* iq, int num) - target_count_create(iq); - if(iq->target_count) - iq->target_count[1] += num; -+ iq->dp_target_count++; -+} -+ -+static void -+target_count_increase_nx(struct iter_qstate* iq, int num) -+{ -+ target_count_create(iq); -+ if(iq->target_count) -+ iq->target_count[2] += num; - } - - /** -@@ -612,13 +629,15 @@ target_count_increase(struct iter_qstate* iq, int num) - * @param subq_ret: if newly allocated, the subquerystate, or NULL if it does - * not need initialisation. - * @param v: if true, validation is done on the subquery. -+ * @param detached: true if this qstate should not attach to the subquery - * @return false on error (malloc). - */ - static int - generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, - uint16_t qclass, struct module_qstate* qstate, int id, - struct iter_qstate* iq, enum iter_state initial_state, -- enum iter_state finalstate, struct module_qstate** subq_ret, int v) -+ enum iter_state finalstate, struct module_qstate** subq_ret, int v, -+ int detached) - { - struct module_qstate* subq = NULL; - struct iter_qstate* subiq = NULL; -@@ -645,12 +664,24 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, - valrec = 1; - } - -- /* attach subquery, lookup existing or make a new one */ -- fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); -- if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, -- &subq)) { -- return 0; -- } -+ if(detached) { -+ struct mesh_state* sub = NULL; -+ fptr_ok(fptr_whitelist_modenv_add_sub( -+ qstate->env->add_sub)); -+ if(!(*qstate->env->add_sub)(qstate, &qinf, -+ qflags, prime, valrec, &subq, &sub)){ -+ return 0; -+ } -+ } -+ else { -+ /* attach subquery, lookup existing or make a new one */ -+ fptr_ok(fptr_whitelist_modenv_attach_sub( -+ qstate->env->attach_sub)); -+ if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, -+ valrec, &subq)) { -+ return 0; -+ } -+ } - *subq_ret = subq; - if(subq) { - /* initialise the new subquery */ -@@ -672,6 +703,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, - subiq->target_count = iq->target_count; - if(iq->target_count) - iq->target_count[0] ++; /* extra reference */ -+ subiq->dp_target_count = 0; - subiq->num_current_queries = 0; - subiq->depth = iq->depth+1; - outbound_list_init(&subiq->outlist); -@@ -715,7 +747,7 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id, - * the normal INIT state logic (which would cause an infloop). */ - if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS, - qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE, -- &subq, 0)) { -+ &subq, 0, 0)) { - verbose(VERB_ALGO, "could not prime root"); - return 0; - } -@@ -805,7 +837,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id, - * redundant INIT state processing. */ - if(!generate_sub_request(stub_dp->name, stub_dp->namelen, - LDNS_RR_TYPE_NS, qclass, qstate, id, iq, -- QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) { -+ QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0, 0)) { - verbose(VERB_ALGO, "could not prime stub"); - (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); - return 1; /* return 1 to make module stop, with error */ -@@ -976,7 +1008,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq, - if(!generate_sub_request(s->rk.dname, s->rk.dname_len, - ntohs(s->rk.type), ntohs(s->rk.rrset_class), - qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) { - verbose(VERB_ALGO, "could not generate addr check"); - return; - } -@@ -1020,7 +1052,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id) - iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass); - if(!generate_sub_request(iq->dp->name, iq->dp->namelen, - LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) { - verbose(VERB_ALGO, "could not generate ns check"); - return; - } -@@ -1077,7 +1109,7 @@ generate_dnskey_prefetch(struct module_qstate* qstate, - iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass); - if(!generate_sub_request(iq->dp->name, iq->dp->namelen, - LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) { - /* we'll be slower, but it'll work */ - verbose(VERB_ALGO, "could not generate dnskey prefetch"); - return; -@@ -1251,6 +1283,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, - iq->refetch_glue = 0; - iq->query_restart_count++; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region); - if(qstate->env->cfg->qname_minimisation) - iq->minimisation_state = INIT_MINIMISE_STATE; -@@ -1613,7 +1646,7 @@ generate_parentside_target_query(struct module_qstate* qstate, - { - struct module_qstate* subq; - if(!generate_sub_request(name, namelen, qtype, qclass, qstate, -- id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) -+ id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) - return 0; - if(subq) { - struct iter_qstate* subiq = -@@ -1664,7 +1697,7 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq, - { - struct module_qstate* subq; - if(!generate_sub_request(name, namelen, qtype, qclass, qstate, -- id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) -+ id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) - return 0; - log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass); - return 1; -@@ -1703,6 +1736,14 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, - "number of glue fetches %d", s, iq->target_count[1]); - return 0; - } -+ if(iq->dp_target_count > MAX_DP_TARGET_COUNT) { -+ char s[LDNS_MAX_DOMAINLEN+1]; -+ 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", -+ s, iq->dp_target_count); -+ return 0; -+ } - - iter_mark_cycle_targets(qstate, iq->dp); - missing = (int)delegpt_count_missing_targets(iq->dp); -@@ -1815,7 +1856,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, - for(a = p->target_list; a; a=a->next_target) { - (void)delegpt_add_addr(iq->dp, qstate->region, - &a->addr, a->addrlen, a->bogus, -- a->lame, a->tls_auth_name); -+ a->lame, a->tls_auth_name, NULL); - } - } - iq->dp->has_parent_side_NS = 1; -@@ -1832,6 +1873,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, - iq->refetch_glue = 1; - iq->query_restart_count++; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - if(qstate->env->cfg->qname_minimisation) - iq->minimisation_state = INIT_MINIMISE_STATE; - return next_state(iq, INIT_REQUEST_STATE); -@@ -1986,7 +2028,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id) - iq->dsns_point, LDNS_RR_TYPE_NS, iq->qchase.qclass); - if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len, - LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) { - return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); - } - -@@ -2039,7 +2081,14 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - "number of sends with %d", iq->sent_count); - return error_response(qstate, id, LDNS_RCODE_SERVFAIL); - } -- -+ if(iq->target_count && iq->target_count[2] > MAX_TARGET_NX) { -+ verbose(VERB_QUERY, "request has exceeded the maximum " -+ " number of nxdomain nameserver lookups with %d", -+ iq->target_count[2]); -+ errinf(qstate, "exceeded the maximum nameserver nxdomains"); -+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL); -+ } -+ - /* Make sure we have a delegation point, otherwise priming failed - * or another failure occurred */ - if(!iq->dp) { -@@ -2139,12 +2188,41 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - iq->qinfo_out.qtype, iq->qinfo_out.qclass, - qstate->query_flags, qstate->region, - qstate->env->scratch, 0); -- if(msg && msg->rep->an_numrrsets == 0 -- && FLAGS_GET_RCODE(msg->rep->flags) == -+ if(msg && FLAGS_GET_RCODE(msg->rep->flags) == - LDNS_RCODE_NOERROR) - /* no need to send query if it is already -- * cached as NOERROR/NODATA */ -+ * cached as NOERROR */ - return 1; -+ if(msg && FLAGS_GET_RCODE(msg->rep->flags) == -+ LDNS_RCODE_NXDOMAIN && -+ qstate->env->need_to_validate && -+ qstate->env->cfg->harden_below_nxdomain) { -+ if(msg->rep->security == sec_status_secure) { -+ iq->response = msg; -+ return final_state(iq); -+ } -+ if(msg->rep->security == sec_status_unchecked) { -+ struct module_qstate* subq = NULL; -+ if(!generate_sub_request( -+ iq->qinfo_out.qname, -+ iq->qinfo_out.qname_len, -+ iq->qinfo_out.qtype, -+ iq->qinfo_out.qclass, -+ qstate, id, iq, -+ INIT_REQUEST_STATE, -+ FINISHED_STATE, &subq, 1, 1)) -+ verbose(VERB_ALGO, -+ "could not validate NXDOMAIN " -+ "response"); -+ } -+ } -+ if(msg && FLAGS_GET_RCODE(msg->rep->flags) == -+ LDNS_RCODE_NXDOMAIN) { -+ /* return and add a label in the next -+ * minimisation iteration. -+ */ -+ return 1; -+ } - } - } - if(iq->minimisation_state == SKIP_MINIMISE_STATE) { -@@ -2219,6 +2297,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - * generated query will immediately be discarded due to depth and - * that servfail is cached, which is not good as opportunism goes. */ - if(iq->depth < ie->max_dependency_depth -+ && iq->num_target_queries == 0 -+ && (!iq->target_count || iq->target_count[2]==0) - && iq->sent_count < TARGET_FETCH_STOP) { - tf_policy = ie->target_fetch_policy[iq->depth]; - } -@@ -2256,6 +2336,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - iq->num_current_queries++; /* RespState decrements it*/ - iq->referral_count++; /* make sure we don't loop */ - iq->sent_count = 0; -+ iq->dp_target_count = 0; - iq->state = QUERY_RESP_STATE; - return 1; - } -@@ -2341,6 +2422,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - iq->num_current_queries++; /* RespState decrements it*/ - iq->referral_count++; /* make sure we don't loop */ - iq->sent_count = 0; -+ iq->dp_target_count = 0; - iq->state = QUERY_RESP_STATE; - return 1; - } -@@ -2607,7 +2689,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - /* Make subrequest to validate intermediate - * NXDOMAIN if harden-below-nxdomain is - * enabled. */ -- if(qstate->env->cfg->harden_below_nxdomain) { -+ if(qstate->env->cfg->harden_below_nxdomain && -+ qstate->env->need_to_validate) { - struct module_qstate* subq = NULL; - log_query_info(VERB_QUERY, - "schedule NXDOMAIN validation:", -@@ -2619,7 +2702,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - iq->response->qinfo.qclass, - qstate, id, iq, - INIT_REQUEST_STATE, -- FINISHED_STATE, &subq, 1)) -+ FINISHED_STATE, &subq, 1, 1)) - verbose(VERB_ALGO, - "could not validate NXDOMAIN " - "response"); -@@ -2702,6 +2785,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - /* Count this as a referral. */ - iq->referral_count++; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - /* see if the next dp is a trust anchor, or a DS was sent - * along, indicating dnssec is expected for next zone */ - iq->dnssec_expected = iter_indicates_dnssec(qstate->env, -@@ -2776,6 +2860,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - iq->dsns_point = NULL; - iq->auth_zone_response = 0; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - if(iq->minimisation_state != MINIMISE_STATE) - /* Only count as query restart when it is not an extra - * query as result of qname minimisation. */ -@@ -2964,7 +3049,7 @@ processPrimeResponse(struct module_qstate* qstate, int id) - if(!generate_sub_request(qstate->qinfo.qname, - qstate->qinfo.qname_len, qstate->qinfo.qtype, - qstate->qinfo.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) { - verbose(VERB_ALGO, "could not generate prime check"); - } - generate_a_aaaa_check(qstate, iq, id); -@@ -2992,6 +3077,7 @@ static void - processTargetResponse(struct module_qstate* qstate, int id, - struct module_qstate* forq) - { -+ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; - struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; - struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id]; - struct ub_packed_rrset_key* rrset; -@@ -3029,7 +3115,7 @@ processTargetResponse(struct module_qstate* qstate, int id, - log_rrset_key(VERB_ALGO, "add parentside glue to dp", - iq->pside_glue); - if(!delegpt_add_rrset(foriq->dp, forq->region, -- iq->pside_glue, 1)) -+ iq->pside_glue, 1, NULL)) - log_err("out of memory adding pside glue"); - } - -@@ -3040,6 +3126,7 @@ processTargetResponse(struct module_qstate* qstate, int id, - * response type was ANSWER. */ - rrset = reply_find_answer_rrset(&iq->qchase, qstate->return_msg->rep); - if(rrset) { -+ int additions = 0; - /* if CNAMEs have been followed - add new NS to delegpt. */ - /* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */ - if(!delegpt_find_ns(foriq->dp, rrset->rk.dname, -@@ -3051,13 +3138,23 @@ processTargetResponse(struct module_qstate* qstate, int id, - } - /* if dpns->lame then set the address(es) lame too */ - if(!delegpt_add_rrset(foriq->dp, forq->region, rrset, -- dpns->lame)) -+ dpns->lame, &additions)) - log_err("out of memory adding targets"); -+ if(!additions) { -+ /* no new addresses, increase the nxns counter, like -+ * this could be a list of wildcards with no new -+ * addresses */ -+ target_count_increase_nx(foriq, 1); -+ } - verbose(VERB_ALGO, "added target response"); - delegpt_log(VERB_ALGO, foriq->dp); - } else { - verbose(VERB_ALGO, "iterator TargetResponse failed"); -+ delegpt_mark_neg(dpns, qstate->qinfo.qtype); - dpns->resolved = 1; /* fail the target */ -+ if((dpns->got4 == 2 || !ie->supports_ipv4) && -+ (dpns->got6 == 2 || !ie->supports_ipv6)) -+ target_count_increase_nx(foriq, 1); - } - } - -@@ -3228,7 +3325,7 @@ processCollectClass(struct module_qstate* qstate, int id) - qstate->qinfo.qname_len, qstate->qinfo.qtype, - c, qstate, id, iq, INIT_REQUEST_STATE, - FINISHED_STATE, &subq, -- (int)!(qstate->query_flags&BIT_CD))) { -+ (int)!(qstate->query_flags&BIT_CD), 0)) { - return error_response(qstate, id, - LDNS_RCODE_SERVFAIL); - } -diff --git a/iterator/iterator.h b/iterator/iterator.h -index 67ffeb1..4b325b5 100644 ---- a/iterator/iterator.h -+++ b/iterator/iterator.h -@@ -55,6 +55,11 @@ struct rbtree_type; - - /** max number of targets spawned for a query and its subqueries */ - #define MAX_TARGET_COUNT 64 -+/** max number of target lookups per qstate, per delegation point */ -+#define MAX_DP_TARGET_COUNT 16 -+/** max number of nxdomains allowed for target lookups for a query and -+ * its subqueries */ -+#define MAX_TARGET_NX 5 - /** max number of query restarts. Determines max number of CNAME chain. */ - #define MAX_RESTART_COUNT 8 - /** max number of referrals. Makes sure resolver does not run away */ -@@ -305,9 +310,14 @@ struct iter_qstate { - int sent_count; - - /** number of target queries spawned in [1], for this query and its -- * subqueries, the malloced-array is shared, [0] refcount. */ -+ * subqueries, the malloced-array is shared, [0] refcount. -+ * in [2] the number of nxdomains is counted. */ - int* target_count; - -+ /** number of target lookups per delegation point. Reset to 0 after -+ * receiving referral answer. Not shared with subqueries. */ -+ int dp_target_count; -+ - /** if true, already tested for ratelimiting and passed the test */ - int ratelimit_ok; - -diff --git a/services/cache/dns.c b/services/cache/dns.c -index 35adc35..23ec68e 100644 ---- a/services/cache/dns.c -+++ b/services/cache/dns.c -@@ -271,7 +271,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_A(dp, region, akey, 0)) { -+ if(!delegpt_add_rrset_A(dp, region, akey, 0, NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -@@ -291,7 +291,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) { -+ if(!delegpt_add_rrset_AAAA(dp, region, akey, 0, NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -@@ -325,7 +325,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) { -+ if(!delegpt_add_rrset_A(dp, region, akey, ns->lame, -+ NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -@@ -345,7 +346,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) { -+ if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame, -+ NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -diff --git a/util/data/dname.c b/util/data/dname.c -index c7360f7..b744f06 100644 ---- a/util/data/dname.c -+++ b/util/data/dname.c -@@ -231,17 +231,28 @@ int - dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2) - { - uint8_t len1, len2; -+ int count1 = 0, count2 = 0; - log_assert(pkt && d1 && d2); - len1 = *d1++; - len2 = *d2++; - while( len1 != 0 || len2 != 0 ) { - /* resolve ptrs */ - if(LABEL_IS_PTR(len1)) { -+ if((size_t)PTR_OFFSET(len1, *d1) -+ >= sldns_buffer_limit(pkt)) -+ return -1; -+ if(count1++ > MAX_COMPRESS_PTRS) -+ return -1; - d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1)); - len1 = *d1++; - continue; - } - if(LABEL_IS_PTR(len2)) { -+ if((size_t)PTR_OFFSET(len2, *d2) -+ >= sldns_buffer_limit(pkt)) -+ return 1; -+ if(count2++ > MAX_COMPRESS_PTRS) -+ return 1; - d2 = sldns_buffer_at(pkt, PTR_OFFSET(len2, *d2)); - len2 = *d2++; - continue; -@@ -300,12 +311,19 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_type h) - uint8_t labuf[LDNS_MAX_LABELLEN+1]; - uint8_t lablen; - int i; -+ int count = 0; - - /* preserve case of query, make hash label by label */ - lablen = *dname++; - while(lablen) { - if(LABEL_IS_PTR(lablen)) { - /* follow pointer */ -+ if((size_t)PTR_OFFSET(lablen, *dname) -+ >= sldns_buffer_limit(pkt)) -+ return h; -+ if(count++ > MAX_COMPRESS_PTRS) -+ return h; -+ - dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname)); - lablen = *dname++; - continue; -@@ -333,6 +351,9 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - while(lablen) { - if(LABEL_IS_PTR(lablen)) { - /* follow pointer */ -+ if((size_t)PTR_OFFSET(lablen, *dname) -+ >= sldns_buffer_limit(pkt)) -+ return; - dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname)); - lablen = *dname++; - continue; -@@ -357,6 +378,7 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname) - { - uint8_t lablen; -+ int count = 0; - if(!out) out = stdout; - if(!dname) return; - -@@ -370,6 +392,15 @@ void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname) - fputs("??compressionptr??", out); - return; - } -+ if((size_t)PTR_OFFSET(lablen, *dname) -+ >= sldns_buffer_limit(pkt)) { -+ fputs("??compressionptr??", out); -+ return; -+ } -+ if(count++ > MAX_COMPRESS_PTRS) { -+ fputs("??compressionptr??", out); -+ return; -+ } - dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname)); - lablen = *dname++; - continue; -diff --git a/util/data/msgparse.c b/util/data/msgparse.c -index 13cad8a..c8a5384 100644 ---- a/util/data/msgparse.c -+++ b/util/data/msgparse.c -@@ -55,7 +55,11 @@ smart_compare(sldns_buffer* pkt, uint8_t* dnow, - { - if(LABEL_IS_PTR(*dnow)) { - /* ptr points to a previous dname */ -- uint8_t* p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1])); -+ uint8_t* p; -+ if((size_t)PTR_OFFSET(dnow[0], dnow[1]) -+ >= sldns_buffer_limit(pkt)) -+ return -1; -+ p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1])); - if( p == dprfirst || p == dprlast ) - return 0; - /* prev dname is also a ptr, both ptrs are the same. */ diff --git a/SOURCES/unbound-1.7.3-anchor-fallback.patch b/SOURCES/unbound-1.7.3-anchor-fallback.patch deleted file mode 100644 index 2470ce1..0000000 --- a/SOURCES/unbound-1.7.3-anchor-fallback.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 81e9f82a8ddd811d7ebafe2fd0ee5af836d0b405 Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Wed, 4 Jul 2018 10:02:16 +0000 -Subject: [PATCH] - Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will - not pass if DNSSEC is not enabled. New option -R allows fallback from - resolv.conf to direct queries. - -git-svn-id: file:///svn/unbound/trunk@4770 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - doc/unbound-anchor.8.in | 5 ++++ - smallapp/unbound-anchor.c | 66 ++++++++++++++++++++++++++++++++++------------- - 2 files changed, 53 insertions(+), 18 deletions(-) - -diff --git a/doc/unbound-anchor.8.in b/doc/unbound-anchor.8.in -index 02a3e781..e114eb25 100644 ---- a/doc/unbound-anchor.8.in -+++ b/doc/unbound-anchor.8.in -@@ -109,6 +109,11 @@ It does so, because the tool when used for bootstrapping the recursive - resolver, cannot use that recursive resolver itself because it is bootstrapping - that server. - .TP -+.B \-R -+Allow fallback from \-f resolv.conf file to direct root servers query. -+It allows you to prefer local resolvers, but fallback automatically -+to direct root query if they do not respond or do not support DNSSEC. -+.TP - .B \-v - More verbose. Once prints informational messages, multiple times may enable - large debug amounts (such as full certificates or byte\-dumps of downloaded -diff --git a/smallapp/unbound-anchor.c b/smallapp/unbound-anchor.c -index b3009108..f3985090 100644 ---- a/smallapp/unbound-anchor.c -+++ b/smallapp/unbound-anchor.c -@@ -192,9 +192,10 @@ usage(void) - printf("-n name signer's subject emailAddress, default %s\n", P7SIGNER); - printf("-4 work using IPv4 only\n"); - printf("-6 work using IPv6 only\n"); -- printf("-f resolv.conf use given resolv.conf to resolve -u name\n"); -- printf("-r root.hints use given root.hints to resolve -u name\n" -+ printf("-f resolv.conf use given resolv.conf\n"); -+ printf("-r root.hints use given root.hints\n" - " builtin root hints are used by default\n"); -+ printf("-R fallback from -f to root query on error\n"); - printf("-v more verbose\n"); - printf("-C conf debug, read config\n"); - printf("-P port use port for https connect, default 443\n"); -@@ -1920,8 +1921,7 @@ static int - do_certupdate(const char* root_anchor_file, const char* root_cert_file, - const char* urlname, const char* xmlname, const char* p7sname, - const char* p7signer, const char* res_conf, const char* root_hints, -- const char* debugconf, int ip4only, int ip6only, int port, -- struct ub_result* dnskey) -+ const char* debugconf, int ip4only, int ip6only, int port) - { - STACK_OF(X509)* cert; - BIO *xml, *p7s; -@@ -1961,7 +1961,6 @@ do_certupdate(const char* root_anchor_file, const char* root_cert_file, - #ifndef S_SPLINT_S - sk_X509_pop_free(cert, X509_free); - #endif -- ub_resolve_free(dnskey); - ip_list_free(ip_list); - return 1; - } -@@ -2199,16 +2198,33 @@ probe_date_allows_certupdate(const char* root_anchor_file) - return 0; - } - -+static struct ub_result * -+fetch_root_key(const char* root_anchor_file, const char* res_conf, -+ const char* root_hints, const char* debugconf, -+ int ip4only, int ip6only) -+{ -+ struct ub_ctx* ctx; -+ struct ub_result* dnskey; -+ -+ ctx = create_unbound_context(res_conf, root_hints, debugconf, -+ ip4only, ip6only); -+ add_5011_probe_root(ctx, root_anchor_file); -+ dnskey = prime_root_key(ctx); -+ ub_ctx_delete(ctx); -+ return dnskey; -+} -+ - /** perform the unbound-anchor work */ - static int - do_root_update_work(const char* root_anchor_file, const char* root_cert_file, - const char* urlname, const char* xmlname, const char* p7sname, - const char* p7signer, const char* res_conf, const char* root_hints, -- const char* debugconf, int ip4only, int ip6only, int force, int port) -+ const char* debugconf, int ip4only, int ip6only, int force, -+ int res_conf_fallback, int port) - { -- struct ub_ctx* ctx; - struct ub_result* dnskey; - int used_builtin = 0; -+ int rcode; - - /* see if builtin rootanchor needs to be provided, or if - * rootanchor is 'revoked-trust-point' */ -@@ -2217,12 +2233,22 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file, - - /* make unbound context with 5011-probe for root anchor, - * and probe . DNSKEY */ -- ctx = create_unbound_context(res_conf, root_hints, debugconf, -- ip4only, ip6only); -- add_5011_probe_root(ctx, root_anchor_file); -- dnskey = prime_root_key(ctx); -- ub_ctx_delete(ctx); -- -+ dnskey = fetch_root_key(root_anchor_file, res_conf, -+ root_hints, debugconf, ip4only, ip6only); -+ rcode = dnskey->rcode; -+ -+ if (res_conf_fallback && res_conf && !dnskey->secure) { -+ if (verb) printf("%s failed, retrying direct\n", res_conf); -+ ub_resolve_free(dnskey); -+ /* try direct query without res_conf */ -+ dnskey = fetch_root_key(root_anchor_file, NULL, -+ root_hints, debugconf, ip4only, ip6only); -+ if (rcode != 0 && dnskey->rcode == 0) { -+ res_conf = NULL; -+ rcode = 0; -+ } -+ } -+ - /* if secure: exit */ - if(dnskey->secure && !force) { - if(verb) printf("success: the anchor is ok\n"); -@@ -2230,18 +2256,18 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file, - return used_builtin; - } - if(force && verb) printf("debug cert update forced\n"); -+ ub_resolve_free(dnskey); - - /* if not (and NOERROR): check date and do certupdate */ -- if((dnskey->rcode == 0 && -+ if((rcode == 0 && - probe_date_allows_certupdate(root_anchor_file)) || force) { - if(do_certupdate(root_anchor_file, root_cert_file, urlname, - xmlname, p7sname, p7signer, res_conf, root_hints, -- debugconf, ip4only, ip6only, port, dnskey)) -+ debugconf, ip4only, ip6only, port)) - return 1; - return used_builtin; - } - if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n"); -- ub_resolve_free(dnskey); - return used_builtin; - } - -@@ -2264,8 +2290,9 @@ int main(int argc, char* argv[]) - const char* root_hints = NULL; - const char* debugconf = NULL; - int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT; -+ int res_conf_fallback = 0; - /* parse the options */ -- while( (c=getopt(argc, argv, "46C:FP:a:c:f:hln:r:s:u:vx:")) != -1) { -+ while( (c=getopt(argc, argv, "46C:FRP:a:c:f:hln:r:s:u:vx:")) != -1) { - switch(c) { - case 'l': - dolist = 1; -@@ -2300,6 +2327,9 @@ int main(int argc, char* argv[]) - case 'r': - root_hints = optarg; - break; -+ case 'R': -+ res_conf_fallback = 1; -+ break; - case 'C': - debugconf = optarg; - break; -@@ -2346,5 +2376,5 @@ int main(int argc, char* argv[]) - - return do_root_update_work(root_anchor_file, root_cert_file, urlname, - xmlname, p7sname, p7signer, res_conf, root_hints, debugconf, -- ip4only, ip6only, force, port); -+ ip4only, ip6only, force, res_conf_fallback, port); - } --- -2.14.4 - diff --git a/SOURCES/unbound-1.7.3-auth-callback.patch b/SOURCES/unbound-1.7.3-auth-callback.patch deleted file mode 100644 index 57a8922..0000000 --- a/SOURCES/unbound-1.7.3-auth-callback.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- a/services/authzone.c 2018-06-14 09:09:01.000000000 +0200 -+++ b/services/authzone.c 2020-04-16 18:55:50.806693241 +0200 -@@ -5139,7 +5139,7 @@ - log_assert(xfr->task_transfer); - lock_basic_lock(&xfr->lock); - env = xfr->task_transfer->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } -@@ -5558,7 +5558,7 @@ - log_assert(xfr->task_transfer); - lock_basic_lock(&xfr->lock); - env = xfr->task_transfer->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return 0; /* stop on quit */ - } -@@ -5619,7 +5619,7 @@ - log_assert(xfr->task_transfer); - lock_basic_lock(&xfr->lock); - env = xfr->task_transfer->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return 0; /* stop on quit */ - } -@@ -5798,7 +5798,7 @@ - log_assert(xfr->task_probe); - lock_basic_lock(&xfr->lock); - env = xfr->task_probe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } -@@ -5829,7 +5829,7 @@ - log_assert(xfr->task_probe); - lock_basic_lock(&xfr->lock); - env = xfr->task_probe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return 0; /* stop on quit */ - } -@@ -6030,7 +6030,7 @@ - log_assert(xfr->task_probe); - lock_basic_lock(&xfr->lock); - env = xfr->task_probe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } -@@ -6089,7 +6089,7 @@ - log_assert(xfr->task_nextprobe); - lock_basic_lock(&xfr->lock); - env = xfr->task_nextprobe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } diff --git a/SOURCES/unbound-1.7.3-crypto-policy-non-compliance-openssl.patch b/SOURCES/unbound-1.7.3-crypto-policy-non-compliance-openssl.patch deleted file mode 100644 index 6d4b906..0000000 --- a/SOURCES/unbound-1.7.3-crypto-policy-non-compliance-openssl.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/util/net_help.c b/util/net_help.c -index a5059b0..a193c36 100644 ---- a/util/net_help.c -+++ b/util/net_help.c -@@ -703,7 +703,7 @@ listen_sslctx_setup(void* ctxt) - #endif - #if defined(SHA256_DIGEST_LENGTH) && defined(USE_ECDSA) - /* if we have sha256, set the cipher list to have no known vulns */ -- if(!SSL_CTX_set_cipher_list(ctx, "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256")) -+ if(!SSL_CTX_set_cipher_list(ctx, "PROFILE=SYSTEM")) - log_crypto_err("could not set cipher list with SSL_CTX_set_cipher_list"); - #endif - diff --git a/SOURCES/unbound-1.7.3-host-any.patch b/SOURCES/unbound-1.7.3-host-any.patch deleted file mode 100644 index 9db4b94..0000000 --- a/SOURCES/unbound-1.7.3-host-any.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/smallapp/unbound-host.c b/smallapp/unbound-host.c -index 53bf3277..f02511fe 100644 ---- a/smallapp/unbound-host.c -+++ b/smallapp/unbound-host.c -@@ -340,6 +340,7 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname) - exit(1); - } - printf("%s\n", s); -+ free(s); - } else printf(" has no %s record", tstr); - printf(" %s\n", secstatus); - } diff --git a/SOURCES/unbound-1.7.3-ipsec-hook.patch b/SOURCES/unbound-1.7.3-ipsec-hook.patch deleted file mode 100644 index 30fea5d..0000000 --- a/SOURCES/unbound-1.7.3-ipsec-hook.patch +++ /dev/null @@ -1,218 +0,0 @@ -diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c -index c8400c6..9e916d6 100644 ---- a/ipsecmod/ipsecmod.c -+++ b/ipsecmod/ipsecmod.c -@@ -162,6 +162,71 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name, - } - - /** -+ * Check if the string passed is a valid domain name with safe characters to -+ * pass to a shell. -+ * This will only allow: -+ * - digits -+ * - alphas -+ * - hyphen (not at the start) -+ * - dot (not at the start, or the only character) -+ * - underscore -+ * @param s: pointer to the string. -+ * @param slen: string's length. -+ * @return true if s only contains safe characters; false otherwise. -+ */ -+static int -+domainname_has_safe_characters(char* s, size_t slen) { -+ size_t i; -+ for(i = 0; i < slen; i++) { -+ if(s[i] == '\0') return 1; -+ if((s[i] == '-' && i != 0) -+ || (s[i] == '.' && (i != 0 || s[1] == '\0')) -+ || (s[i] == '_') || (s[i] >= '0' && s[i] <= '9') -+ || (s[i] >= 'A' && s[i] <= 'Z') -+ || (s[i] >= 'a' && s[i] <= 'z')) { -+ continue; -+ } -+ return 0; -+ } -+ return 1; -+} -+ -+/** -+ * Check if the stringified IPSECKEY RDATA contains safe characters to pass to -+ * a shell. -+ * This is only relevant for checking the gateway when the gateway type is 3 -+ * (domainname). -+ * @param s: pointer to the string. -+ * @param slen: string's length. -+ * @return true if s contains only safe characters; false otherwise. -+ */ -+static int -+ipseckey_has_safe_characters(char* s, size_t slen) { -+ int precedence, gateway_type, algorithm; -+ char* gateway; -+ gateway = (char*)calloc(slen, sizeof(char)); -+ if(!gateway) { -+ log_err("ipsecmod: out of memory when calling the hook"); -+ return 0; -+ } -+ if(sscanf(s, "%d %d %d %s ", -+ &precedence, &gateway_type, &algorithm, gateway) != 4) { -+ free(gateway); -+ return 0; -+ } -+ if(gateway_type != 3) { -+ free(gateway); -+ return 1; -+ } -+ if(domainname_has_safe_characters(gateway, slen)) { -+ free(gateway); -+ return 1; -+ } -+ free(gateway); -+ return 0; -+} -+ -+/** - * Prepare the data and call the hook. - * - * @param qstate: query state. -@@ -175,7 +240,7 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq, - { - size_t slen, tempdata_len, tempstring_len, i; - char str[65535], *s, *tempstring; -- int w; -+ int w = 0, w_temp, qtype; - struct ub_packed_rrset_key* rrset_key; - struct packed_rrset_data* rrset_data; - uint8_t *tempdata; -@@ -192,9 +257,9 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq, - memset(s, 0, slen); - - /* Copy the hook into the buffer. */ -- sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook); -+ w += sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - /* Copy the qname into the buffer. */ - tempstring = sldns_wire2str_dname(qstate->qinfo.qname, - qstate->qinfo.qname_len); -@@ -202,68 +267,96 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq, - log_err("ipsecmod: out of memory when calling the hook"); - return 0; - } -- sldns_str_print(&s, &slen, "\"%s\"", tempstring); -+ if(!domainname_has_safe_characters(tempstring, strlen(tempstring))) { -+ log_err("ipsecmod: qname has unsafe characters"); -+ free(tempstring); -+ return 0; -+ } -+ w += sldns_str_print(&s, &slen, "\"%s\"", tempstring); - free(tempstring); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - /* Copy the IPSECKEY TTL into the buffer. */ - rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data; -- sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl); -+ w += sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -- /* Copy the A/AAAA record(s) into the buffer. Start and end this section -- * with a double quote. */ -+ w += sldns_str_print(&s, &slen, " "); - rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo, - qstate->return_msg->rep); -+ /* Double check that the records are indeed A/AAAA. -+ * This should never happen as this function is only executed for A/AAAA -+ * queries but make sure we don't pass anything other than A/AAAA to the -+ * shell. */ -+ qtype = ntohs(rrset_key->rk.type); -+ if(qtype != LDNS_RR_TYPE_AAAA && qtype != LDNS_RR_TYPE_A) { -+ log_err("ipsecmod: Answer is not of A or AAAA type"); -+ return 0; -+ } - rrset_data = (struct packed_rrset_data*)rrset_key->entry.data; -- sldns_str_print(&s, &slen, "\""); -+ /* Copy the A/AAAA record(s) into the buffer. Start and end this section -+ * with a double quote. */ -+ w += sldns_str_print(&s, &slen, "\""); - for(i=0; icount; i++) { - if(i > 0) { - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - } - /* Ignore the first two bytes, they are the rr_data len. */ -- w = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2, -+ w_temp = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2, - rrset_data->rr_len[i] - 2, s, slen, qstate->qinfo.qtype); -- if(w < 0) { -+ if(w_temp < 0) { - /* Error in printout. */ -- return -1; -- } else if((size_t)w >= slen) { -+ log_err("ipsecmod: Error in printing IP address"); -+ return 0; -+ } else if((size_t)w_temp >= slen) { - s = NULL; /* We do not want str to point outside of buffer. */ - slen = 0; -- return -1; -+ log_err("ipsecmod: shell command too long"); -+ return 0; - } else { -- s += w; -- slen -= w; -+ s += w_temp; -+ slen -= w_temp; -+ w += w_temp; - } - } -- sldns_str_print(&s, &slen, "\""); -+ w += sldns_str_print(&s, &slen, "\""); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - /* Copy the IPSECKEY record(s) into the buffer. Start and end this section - * with a double quote. */ -- sldns_str_print(&s, &slen, "\""); -+ w += sldns_str_print(&s, &slen, "\""); - rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data; - for(i=0; icount; i++) { - if(i > 0) { - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - } - /* Ignore the first two bytes, they are the rr_data len. */ - tempdata = rrset_data->rr_data[i] + 2; - tempdata_len = rrset_data->rr_len[i] - 2; - /* Save the buffer pointers. */ - tempstring = s; tempstring_len = slen; -- w = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, &slen, -- NULL, 0); -+ w_temp = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, -+ &slen, NULL, 0); - /* There was an error when parsing the IPSECKEY; reset the buffer - * pointers to their previous values. */ -- if(w == -1){ -+ if(w_temp == -1) { - s = tempstring; slen = tempstring_len; -+ } else if(w_temp > 0) { -+ if(!ipseckey_has_safe_characters( -+ tempstring, tempstring_len - slen)) { -+ log_err("ipsecmod: ipseckey has unsafe characters"); -+ return 0; -+ } -+ w += w_temp; - } - } -- sldns_str_print(&s, &slen, "\""); -- verbose(VERB_ALGO, "ipsecmod: hook command: '%s'", str); -+ w += sldns_str_print(&s, &slen, "\""); -+ if(w >= (int)sizeof(str)) { -+ log_err("ipsecmod: shell command too long"); -+ return 0; -+ } -+ verbose(VERB_ALGO, "ipsecmod: shell command: '%s'", str); - /* ipsecmod-hook should return 0 on success. */ - if(system(str) != 0) - return 0; diff --git a/SOURCES/unbound-1.7.3-ksk-2010-revoked.patch b/SOURCES/unbound-1.7.3-ksk-2010-revoked.patch deleted file mode 100644 index a01109c..0000000 --- a/SOURCES/unbound-1.7.3-ksk-2010-revoked.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/smallapp/unbound-anchor.c b/smallapp/unbound-anchor.c -index 2bf5b3ab..a30523c7 100644 ---- a/smallapp/unbound-anchor.c -+++ b/smallapp/unbound-anchor.c -@@ -246,9 +246,7 @@ get_builtin_ds(void) - return - /* The anchors must start on a new line with ". IN DS and end with \n"[;] - * because the makedist script greps on the source here */ --/* anchor 19036 is from 2010 */ - /* anchor 20326 is from 2017 */ --". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n" - ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n"; - } - diff --git a/SOURCES/unbound-1.7.3-security-hardening.patch b/SOURCES/unbound-1.7.3-security-hardening.patch deleted file mode 100644 index 930bbad..0000000 --- a/SOURCES/unbound-1.7.3-security-hardening.patch +++ /dev/null @@ -1,677 +0,0 @@ -diff --git a/config.h.in b/config.h.in -index 04356f3..3b06bfa 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -666,6 +666,9 @@ - /* Shared data */ - #undef SHARE_DIR - -+/* The size of `size_t', as computed by sizeof. */ -+#undef SIZEOF_SIZE_T -+ - /* The size of `time_t', as computed by sizeof. */ - #undef SIZEOF_TIME_T - -diff --git a/configure.ac b/configure.ac -index c5e0c7b..1bff4ed 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -371,6 +371,7 @@ AC_INCLUDES_DEFAULT - # endif - #endif - ]) -+AC_CHECK_SIZEOF(size_t) - - # add option to disable the evil rpath - ACX_ARG_RPATH -diff --git a/contrib/create_unbound_ad_servers.sh b/contrib/create_unbound_ad_servers.sh -index d31f078..49fdbff 100644 ---- a/contrib/create_unbound_ad_servers.sh -+++ b/contrib/create_unbound_ad_servers.sh -@@ -9,12 +9,13 @@ - # Variables - dst_dir="/etc/opt/csw/unbound" - work_dir="/tmp" --list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" -+list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" - - # OS commands - CAT=`which cat` - ECHO=`which echo` - WGET=`which wget` -+TR=`which tr` - - # Check Wget installed - if [ ! -f $WGET ]; then -@@ -22,8 +23,10 @@ if [ ! -f $WGET ]; then - exit 1 - fi - -+# remove special characters with tr to protect unbound.conf - $WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \ - $CAT $work_dir/yoyo_ad_servers | \ -+$TR -d '";$\\' | \ - while read line ; \ - do \ - $ECHO "local-zone: \"$line\" redirect" ;\ -@@ -36,4 +39,4 @@ echo "Done." - # the unbound_ad_servers file: - # - # include: $dst_dir/unbound_ad_servers --# -\ No newline at end of file -+# -diff --git a/daemon/daemon.c b/daemon/daemon.c -index 6820e11..1b4f329 100644 ---- a/daemon/daemon.c -+++ b/daemon/daemon.c -@@ -426,9 +426,7 @@ daemon_create_workers(struct daemon* daemon) - int* shufport; - log_assert(daemon && daemon->cfg); - if(!daemon->rand) { -- unsigned int seed = (unsigned int)time(NULL) ^ -- (unsigned int)getpid() ^ 0x438; -- daemon->rand = ub_initstate(seed, NULL); -+ daemon->rand = ub_initstate(NULL); - if(!daemon->rand) - fatal_exit("could not init random generator"); - hash_set_raninit((uint32_t)ub_random(daemon->rand)); -diff --git a/daemon/worker.c b/daemon/worker.c -index 3acecc1..8354010 100644 ---- a/daemon/worker.c -+++ b/daemon/worker.c -@@ -1629,18 +1629,14 @@ worker_create(struct daemon* daemon, int id, int* ports, int n) - return NULL; - } - /* create random state here to avoid locking trouble in RAND_bytes */ -- seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ -- (((unsigned int)worker->thread_num)<<17); -- /* shift thread_num so it does not match out pid bits */ -- if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) { -- seed = 0; -+ if(!(worker->rndstate = ub_initstate(daemon->rand))) { - log_err("could not init random numbers."); - tube_delete(worker->cmd); - free(worker->ports); - free(worker); - return NULL; - } -- seed = 0; -+ explicit_bzero(&seed, sizeof(seed)); - #ifdef USE_DNSTAP - if(daemon->cfg->dnstap) { - log_assert(daemon->dtenv != NULL); -diff --git a/dns64/dns64.c b/dns64/dns64.c -index 7889d72..300202c 100644 ---- a/dns64/dns64.c -+++ b/dns64/dns64.c -@@ -782,6 +782,16 @@ dns64_inform_super(struct module_qstate* qstate, int id, - * Signal that the sub-query is finished, no matter whether we are - * successful or not. This lets the state machine terminate. - */ -+ if(!super->minfo[id]) { -+ super->minfo[id] = (enum dns64_qstate *)regional_alloc(super->region, -+ sizeof(*(super->minfo[id]))); -+ if(!super->minfo[id]) { -+ log_err("out of memory"); -+ super->return_rcode = LDNS_RCODE_SERVFAIL; -+ super->return_msg = NULL; -+ return; -+ } -+ } - super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED; - - /* If there is no successful answer, we're done. */ -diff --git a/dnscrypt/dnscrypt.c b/dnscrypt/dnscrypt.c -index 3545d3d..7dd2ce5 100644 ---- a/dnscrypt/dnscrypt.c -+++ b/dnscrypt/dnscrypt.c -@@ -732,6 +732,11 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg) - ); - continue; - } -+ if((unsigned)strlen(dnscenv->provider_name) >= (unsigned)0xffff0000) { -+ /* guard against integer overflow in rrlen calculation */ -+ verbose(VERB_OPS, "cert #%" PRIu32 " is too long", serial); -+ continue; -+ } - rrlen = strlen(dnscenv->provider_name) + - strlen(ttl_class_type) + - 4 * sizeof(struct SignedCert) + // worst case scenario -diff --git a/doc/Changelog b/doc/Changelog -index bb74461..4cb080e 100644 ---- a/doc/Changelog -+++ b/doc/Changelog -@@ -1,3 +1,55 @@ -+3 December 2019: Wouter -+ - Fix Assert Causing DoS in synth_cname(), -+ reported by X41 D-Sec. -+ - Fix Assert Causing DoS in dname_pkt_copy(), -+ reported by X41 D-Sec. -+ - Fix OOB Read in sldns_wire2str_dname_scan(), -+ reported by X41 D-Sec. -+ - Fix Out of Bounds Write in sldns_str2wire_str_buf(), -+ reported by X41 D-Sec. -+ - Fix Out of Bounds Write in sldns_b64_pton(), -+ fixed by check in sldns_str2wire_int16_data_buf(), -+ reported by X41 D-Sec. -+ - Fix Insufficient Handling of Compressed Names in dname_pkt_copy(), -+ reported by X41 D-Sec. -+ - Fix Out of Bound Write Compressed Names in rdata_copy(), -+ reported by X41 D-Sec. -+ - Fix Hang in sldns_wire2str_pkt_scan(), -+ reported by X41 D-Sec. -+ -+20 November 2019: Wouter -+ - Fix Out of Bounds Read in rrinternal_get_owner(), -+ reported by X41 D-Sec. -+ - Fix Race Condition in autr_tp_create(), -+ reported by X41 D-Sec. -+ - Fix Shared Memory World Writeable, -+ reported by X41 D-Sec. -+ - Adjust unbound-control to make stats_shm a read only operation. -+ - Fix Weak Entropy Used For Nettle, -+ reported by X41 D-Sec. -+ - Fix Randomness Error not Handled Properly, -+ reported by X41 D-Sec. -+ - Fix Out-of-Bounds Read in dname_valid(), -+ reported by X41 D-Sec. -+ - Fix Config Injection in create_unbound_ad_servers.sh, -+ reported by X41 D-Sec. -+ -+19 November 2019: Wouter -+ - Fix Integer Overflow in Regional Allocator, -+ reported by X41 D-Sec. -+ - Fix Unchecked NULL Pointer in dns64_inform_super() -+ and ipsecmod_new(), reported by X41 D-Sec. -+ - Fix Out-of-bounds Read in rr_comment_dnskey(), -+ reported by X41 D-Sec. -+ - Fix Integer Overflows in Size Calculations, -+ reported by X41 D-Sec. -+ - Fix Integer Overflow to Buffer Overflow in -+ sldns_str2wire_dname_buf_origin(), reported by X41 D-Sec. -+ - Fix Out of Bounds Read in sldns_str2wire_dname(), -+ reported by X41 D-Sec. -+ - Fix Out of Bounds Write in sldns_bget_token_par(), -+ reported by X41 D-Sec. -+ - 30 November 2018: Wouter - - log-tag-queryreply: yes in unbound.conf tags the log-queries and - log-replies in the log file for easier log filter maintenance. -diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c -index 3572f12..1422a62 100644 ---- a/ipsecmod/ipsecmod.c -+++ b/ipsecmod/ipsecmod.c -@@ -103,11 +103,11 @@ ipsecmod_new(struct module_qstate* qstate, int id) - { - struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)regional_alloc( - qstate->region, sizeof(struct ipsecmod_qstate)); -- memset(iq, 0, sizeof(*iq)); - qstate->minfo[id] = iq; - if(!iq) - return 0; - /* Initialise it. */ -+ memset(iq, 0, sizeof(*iq)); - iq->enabled = qstate->env->cfg->ipsecmod_enabled; - iq->is_whitelisted = ipsecmod_domain_is_whitelisted( - (struct ipsecmod_env*)qstate->env->modinfo[id], qstate->qinfo.qname, -diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c -index 8230d17..942c3d5 100644 ---- a/iterator/iter_scrub.c -+++ b/iterator/iter_scrub.c -@@ -231,6 +231,10 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset, - size_t dtarglen; - if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt)) - return 0; -+ if(qnamelen <= dname_rrset->dname_len) -+ return 0; -+ if(qnamelen == 0) -+ return 0; - log_assert(qnamelen > dname_rrset->dname_len); - /* DNAME from com. to net. with qname example.com. -> example.net. */ - /* so: \3com\0 to \3net\0 and qname \7example\3com\0 */ -diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c -index 275e8d2..a8979c2 100644 ---- a/libunbound/libunbound.c -+++ b/libunbound/libunbound.c -@@ -83,7 +83,6 @@ - static struct ub_ctx* ub_ctx_create_nopipe(void) - { - struct ub_ctx* ctx; -- unsigned int seed; - #ifdef USE_WINSOCK - int r; - WSADATA wsa_data; -@@ -107,15 +106,12 @@ static struct ub_ctx* ub_ctx_create_nopipe(void) - return NULL; - } - alloc_init(&ctx->superalloc, NULL, 0); -- seed = (unsigned int)time(NULL) ^ (unsigned int)getpid(); -- if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) { -- seed = 0; -+ if(!(ctx->seed_rnd = ub_initstate(NULL))) { - ub_randfree(ctx->seed_rnd); - free(ctx); - errno = ENOMEM; - return NULL; - } -- seed = 0; - lock_basic_init(&ctx->qqpipe_lock); - lock_basic_init(&ctx->rrpipe_lock); - lock_basic_init(&ctx->cfglock); -diff --git a/libunbound/libworker.c b/libunbound/libworker.c -index 3dcaa78..07a08c6 100644 ---- a/libunbound/libworker.c -+++ b/libunbound/libworker.c -@@ -122,7 +122,6 @@ libworker_delete_event(struct libworker* w) - static struct libworker* - libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) - { -- unsigned int seed; - struct libworker* w = (struct libworker*)calloc(1, sizeof(*w)); - struct config_file* cfg = ctx->env->cfg; - int* ports; -@@ -177,17 +176,13 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) - } - w->env->worker = (struct worker*)w; - w->env->probe_timer = NULL; -- seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ -- (((unsigned int)w->thread_num)<<17); -- seed ^= (unsigned int)w->env->alloc->next_id; - if(!w->is_bg || w->is_bg_thread) { - lock_basic_lock(&ctx->cfglock); - } -- if(!(w->env->rnd = ub_initstate(seed, ctx->seed_rnd))) { -+ if(!(w->env->rnd = ub_initstate(ctx->seed_rnd))) { - if(!w->is_bg || w->is_bg_thread) { - lock_basic_unlock(&ctx->cfglock); - } -- seed = 0; - libworker_delete(w); - return NULL; - } -@@ -207,7 +202,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) - hash_set_raninit((uint32_t)ub_random(w->env->rnd)); - } - } -- seed = 0; - - if(eb) - w->base = comm_base_create_event(eb); -diff --git a/respip/respip.c b/respip/respip.c -index 2e9313f..7d2a588 100644 ---- a/respip/respip.c -+++ b/respip/respip.c -@@ -475,10 +475,16 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region) - if(!ck->rk.dname) - return NULL; - -+ if((unsigned)data->count >= 0xffff00U) -+ return NULL; /* guard against integer overflow in dsize */ - dsize = sizeof(struct packed_rrset_data) + data->count * - (sizeof(size_t)+sizeof(uint8_t*)+sizeof(time_t)); -- for(i=0; icount; i++) -+ for(i=0; icount; i++) { -+ if((unsigned)dsize >= 0x0fffffffU || -+ (unsigned)data->rr_len[i] >= 0x0fffffffU) -+ return NULL; /* guard against integer overflow */ - dsize += data->rr_len[i]; -+ } - d = regional_alloc(region, dsize); - if(!d) - return NULL; -diff --git a/sldns/parse.c b/sldns/parse.c -index b62c405..b30264e 100644 ---- a/sldns/parse.c -+++ b/sldns/parse.c -@@ -325,8 +325,14 @@ sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim, - if (c == '\n' && p != 0) { - /* in parentheses */ - /* do not write ' ' if we want to skip spaces */ -- if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) -+ if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) { -+ /* check for space for the space character */ -+ if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { -+ *t = '\0'; -+ return -1; -+ } - *t++ = ' '; -+ } - lc = c; - continue; - } -diff --git a/sldns/str2wire.c b/sldns/str2wire.c -index 1a51bb6..414b7b8 100644 ---- a/sldns/str2wire.c -+++ b/sldns/str2wire.c -@@ -150,6 +150,10 @@ int sldns_str2wire_dname_buf_origin(const char* str, uint8_t* buf, size_t* len, - if(s) return s; - - if(rel && origin && dlen > 0) { -+ if((unsigned)dlen >= 0x00ffffffU || -+ (unsigned)origin_len >= 0x00ffffffU) -+ /* guard against integer overflow in addition */ -+ return RET_ERR(LDNS_WIREPARSE_ERR_GENERAL, *len); - if(dlen + origin_len - 1 > LDNS_MAX_DOMAINLEN) - return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, - LDNS_MAX_DOMAINLEN); -@@ -168,7 +172,9 @@ uint8_t* sldns_str2wire_dname(const char* str, size_t* len) - uint8_t dname[LDNS_MAX_DOMAINLEN+1]; - *len = sizeof(dname); - if(sldns_str2wire_dname_buf(str, dname, len) == 0) { -- uint8_t* r = (uint8_t*)malloc(*len); -+ uint8_t* r; -+ if(*len > sizeof(dname)) return NULL; -+ r = (uint8_t*)malloc(*len); - if(r) return memcpy(r, dname, *len); - } - *len = 0; -@@ -187,6 +193,9 @@ rrinternal_get_owner(sldns_buffer* strbuf, uint8_t* rr, size_t* len, - sldns_buffer_position(strbuf)); - } - -+ if(token_len < 2) /* make sure there is space to read "@" or "" */ -+ return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, -+ sldns_buffer_position(strbuf)); - if(strcmp(token, "@") == 0) { - uint8_t* tocopy; - if (origin) { -@@ -1094,7 +1103,7 @@ int sldns_str2wire_str_buf(const char* str, uint8_t* rd, size_t* len) - while(sldns_parse_char(&ch, &s)) { - if(sl >= 255) - return RET_ERR(LDNS_WIREPARSE_ERR_INVALID_STR, s-str); -- if(*len < sl+1) -+ if(*len < sl+2) - return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, - s-str); - rd[++sl] = ch; -@@ -2095,6 +2104,8 @@ int sldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len) - char* s; - int n; - n = strtol(str, &s, 10); -+ if(n < 0) /* negative number not allowed */ -+ return LDNS_WIREPARSE_ERR_SYNTAX; - if(*len < ((size_t)n)+2) - return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; - if(n > 65535) -diff --git a/sldns/wire2str.c b/sldns/wire2str.c -index 832239f..a95c9b3 100644 ---- a/sldns/wire2str.c -+++ b/sldns/wire2str.c -@@ -585,6 +585,7 @@ static int rr_comment_dnskey(char** s, size_t* slen, uint8_t* rr, - if(rrlen < dname_off + 10) return 0; - rdlen = sldns_read_uint16(rr+dname_off+8); - if(rrlen < dname_off + 10 + rdlen) return 0; -+ if(rdlen < 2) return 0; - rdata = rr + dname_off + 10; - flags = (int)sldns_read_uint16(rdata); - w += sldns_str_print(s, slen, " ;{"); -@@ -781,7 +782,7 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, - /* spool labels onto the string, use compression if its there */ - uint8_t* pos = *d; - unsigned i, counter=0; -- const unsigned maxcompr = 1000; /* loop detection, max compr ptrs */ -+ const unsigned maxcompr = 256; /* loop detection, max compr ptrs */ - int in_buf = 1; - if(*dlen == 0) return sldns_str_print(s, slen, "ErrorMissingDname"); - if(*pos == 0) { -@@ -789,7 +790,7 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, - (*dlen)--; - return sldns_str_print(s, slen, "."); - } -- while(*pos) { -+ while((!pkt || pos < pkt+pktlen) && *pos) { - /* read label length */ - uint8_t labellen = *pos++; - if(in_buf) { (*d)++; (*dlen)--; } -diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c -index d165417..2884309 100644 ---- a/smallapp/unbound-control.c -+++ b/smallapp/unbound-control.c -@@ -407,19 +407,19 @@ static void print_stats_shm(const char* cfgfile) - if(!config_read(cfg, cfgfile, NULL)) - fatal_exit("could not read config file"); - /* get shm segments */ -- id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R|SHM_W); -+ id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R); - if(id_ctl == -1) { - fatal_exit("shmget(%d): %s", cfg->shm_key, strerror(errno)); - } -- id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R|SHM_W); -+ id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R); - if(id_arr == -1) { - fatal_exit("shmget(%d): %s", cfg->shm_key+1, strerror(errno)); - } -- shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, 0); -+ shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, SHM_RDONLY); - if(shm_stat == (void*)-1) { - fatal_exit("shmat(%d): %s", id_ctl, strerror(errno)); - } -- stats = (struct ub_stats_info*)shmat(id_arr, NULL, 0); -+ stats = (struct ub_stats_info*)shmat(id_arr, NULL, SHM_RDONLY); - if(stats == (void*)-1) { - fatal_exit("shmat(%d): %s", id_arr, strerror(errno)); - } -diff --git a/testcode/unitmain.c b/testcode/unitmain.c -index fecde80..96a6654 100644 ---- a/testcode/unitmain.c -+++ b/testcode/unitmain.c -@@ -537,10 +537,8 @@ rnd_test(void) - struct ub_randstate* r; - int num = 1000, i; - long int a[1000]; -- unsigned int seed = (unsigned)time(NULL); - unit_show_feature("ub_random"); -- printf("ub_random seed is %u\n", seed); -- unit_assert( (r = ub_initstate(seed, NULL)) ); -+ unit_assert( (r = ub_initstate(NULL)) ); - for(i=0; i= 0); -diff --git a/util/data/dname.c b/util/data/dname.c -index b744f06..923be02 100644 ---- a/util/data/dname.c -+++ b/util/data/dname.c -@@ -75,6 +75,8 @@ dname_valid(uint8_t* dname, size_t maxlen) - { - size_t len = 0; - size_t labellen; -+ if(maxlen == 0) -+ return 0; /* too short, shortest is '0' root label */ - labellen = *dname++; - while(labellen) { - if(labellen&0xc0) -@@ -345,11 +347,17 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_type h) - void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - { - /* copy over the dname and decompress it at the same time */ -+ size_t comprcount = 0; - size_t len = 0; - uint8_t lablen; - lablen = *dname++; - while(lablen) { - if(LABEL_IS_PTR(lablen)) { -+ if(comprcount++ > MAX_COMPRESS_PTRS) { -+ /* too many compression pointers */ -+ *to = 0; /* end the result prematurely */ -+ return; -+ } - /* follow pointer */ - if((size_t)PTR_OFFSET(lablen, *dname) - >= sldns_buffer_limit(pkt)) -@@ -358,6 +366,10 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - lablen = *dname++; - continue; - } -+ if(lablen > LDNS_MAX_LABELLEN) { -+ *to = 0; /* end the result prematurely */ -+ return; -+ } - log_assert(lablen <= LDNS_MAX_LABELLEN); - len += (size_t)lablen+1; - if(len >= LDNS_MAX_DOMAINLEN) { -diff --git a/util/data/msgreply.c b/util/data/msgreply.c -index df2131c..dbae34d 100644 ---- a/util/data/msgreply.c -+++ b/util/data/msgreply.c -@@ -238,10 +238,10 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, - break; - } - if(len) { -+ log_assert(len <= pkt_len); - memmove(to, sldns_buffer_current(pkt), len); - to += len; - sldns_buffer_skip(pkt, (ssize_t)len); -- log_assert(len <= pkt_len); - pkt_len -= len; - } - rdf++; -diff --git a/util/random.c b/util/random.c -index 8332960..9380502 100644 ---- a/util/random.c -+++ b/util/random.c -@@ -86,8 +86,7 @@ ub_systemseed(unsigned int ATTR_UNUSED(seed)) - } - - struct ub_randstate* --ub_initstate(unsigned int ATTR_UNUSED(seed), -- struct ub_randstate* ATTR_UNUSED(from)) -+ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) - { - struct ub_randstate* s = (struct ub_randstate*)malloc(1); - if(!s) { -@@ -123,8 +122,8 @@ void ub_systemseed(unsigned int ATTR_UNUSED(seed)) - { - } - --struct ub_randstate* ub_initstate(unsigned int ATTR_UNUSED(seed), -- struct ub_randstate* ATTR_UNUSED(from)) -+struct ub_randstate* -+ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) - { - struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); - if(!s) { -@@ -140,7 +139,9 @@ long int ub_random(struct ub_randstate* ATTR_UNUSED(state)) - /* random 31 bit value. */ - SECStatus s = PK11_GenerateRandom((unsigned char*)&x, (int)sizeof(x)); - if(s != SECSuccess) { -- log_err("PK11_GenerateRandom error: %s", -+ /* unbound needs secure randomness for randomized -+ * ID bits and port numbers in packets to upstream servers */ -+ fatal_exit("PK11_GenerateRandom error: %s", - PORT_ErrorToString(PORT_GetError())); - } - return x & MAX_VALUE; -@@ -166,8 +167,7 @@ void ub_systemseed(unsigned int ATTR_UNUSED(seed)) - log_err("Re-seeding not supported, generator untouched"); - } - --struct ub_randstate* ub_initstate(unsigned int seed, -- struct ub_randstate* ATTR_UNUSED(from)) -+struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) - { - struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); - uint8_t buf[YARROW256_SEED_FILE_SIZE]; -@@ -183,15 +183,10 @@ struct ub_randstate* ub_initstate(unsigned int seed, - yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf); - s->seeded = yarrow256_is_seeded(&s->ctx); - } else { -- /* Stretch the uint32 input seed and feed it to Yarrow */ -- uint32_t v = seed; -- size_t i; -- for(i=0; i < (YARROW256_SEED_FILE_SIZE/sizeof(seed)); i++) { -- memmove(buf+i*sizeof(seed), &v, sizeof(seed)); -- v = v*seed + (uint32_t)i; -- } -- yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf); -- s->seeded = yarrow256_is_seeded(&s->ctx); -+ log_err("nettle random(yarrow) cannot initialize, " -+ "getentropy failed: %s", strerror(errno)); -+ free(s); -+ return NULL; - } - - return s; -diff --git a/util/random.h b/util/random.h -index a05a994..e75157d 100644 ---- a/util/random.h -+++ b/util/random.h -@@ -57,15 +57,12 @@ void ub_systemseed(unsigned int seed); - - /** - * Initialize a random generator state for use -- * @param seed: seed value to create state contents. -- * (ignored for arc4random). - * @param from: if not NULL, the seed is taken from this random structure. - * can be used to seed random states via a parent-random-state that - * is itself seeded with entropy. - * @return new state or NULL alloc failure. - */ --struct ub_randstate* ub_initstate(unsigned int seed, -- struct ub_randstate* from); -+struct ub_randstate* ub_initstate(struct ub_randstate* from); - - /** - * Generate next random number from the state passed along. -diff --git a/util/regional.c b/util/regional.c -index 899a54e..5be09eb 100644 ---- a/util/regional.c -+++ b/util/regional.c -@@ -120,8 +120,18 @@ regional_destroy(struct regional *r) - void * - regional_alloc(struct regional *r, size_t size) - { -- size_t a = ALIGN_UP(size, ALIGNMENT); -+ size_t a; - void *s; -+ if( -+#if SIZEOF_SIZE_T == 8 -+ (unsigned long long)size >= 0xffffffffffffff00ULL -+#else -+ (unsigned)size >= (unsigned)0xffffff00UL -+#endif -+ ) -+ return NULL; /* protect against integer overflow in -+ malloc and ALIGN_UP */ -+ a = ALIGN_UP(size, ALIGNMENT); - /* large objects */ - if(a > REGIONAL_LARGE_OBJECT_SIZE) { - s = malloc(ALIGNMENT + size); -diff --git a/util/shm_side/shm_main.c b/util/shm_side/shm_main.c -index a783c09..69bee4d 100644 ---- a/util/shm_side/shm_main.c -+++ b/util/shm_side/shm_main.c -@@ -121,7 +121,7 @@ int shm_main_init(struct daemon* daemon) - shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL); - - /* SHM: Create the segment */ -- daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0666); -+ daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0644); - - if (daemon->shm_info->id_ctl < 0) - { -@@ -134,7 +134,7 @@ int shm_main_init(struct daemon* daemon) - return 0; - } - -- daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0666); -+ daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0644); - - if (daemon->shm_info->id_arr < 0) - { -diff --git a/validator/autotrust.c b/validator/autotrust.c -index 7bc5577..e19bd7b 100644 ---- a/validator/autotrust.c -+++ b/validator/autotrust.c -@@ -370,10 +370,10 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, - free(tp); - return NULL; - } -- lock_basic_unlock(&anchors->lock); - lock_basic_init(&tp->lock); - lock_protect(&tp->lock, tp, sizeof(*tp)); - lock_protect(&tp->lock, tp->autr, sizeof(*tp->autr)); -+ lock_basic_unlock(&anchors->lock); - return tp; - } - diff --git a/SOURCES/unbound-1.7.3-symlink-traversal.patch b/SOURCES/unbound-1.7.3-symlink-traversal.patch deleted file mode 100644 index 0c06794..0000000 --- a/SOURCES/unbound-1.7.3-symlink-traversal.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff --git a/unbound-1.7.3/daemon/unbound.c b/unbound-1.7.3/daemon/unbound.c -index 1383110..66ed61d 100644 ---- a/daemon/unbound.c -+++ b/daemon/unbound.c -@@ -327,18 +327,32 @@ readpid (const char* file) - static void - writepid (const char* pidfile, pid_t pid) - { -- FILE* f; -+ int fd; -+ char pidbuf[32]; -+ size_t count = 0; -+ snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long)pid); - -- if ((f = fopen(pidfile, "w")) == NULL ) { -+ if((fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC -+#ifdef O_NOFOLLOW -+ | O_NOFOLLOW -+#endif -+ , 0644)) == -1) { - log_err("cannot open pidfile %s: %s", - pidfile, strerror(errno)); - return; - } -- if(fprintf(f, "%lu\n", (unsigned long)pid) < 0) { -- log_err("cannot write to pidfile %s: %s", -- pidfile, strerror(errno)); -+ while(count < strlen(pidbuf)) { -+ ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count); -+ if(r == -1) { -+ if(errno == EAGAIN || errno == EINTR) -+ continue; -+ log_err("cannot write to pidfile %s: %s", -+ pidfile, strerror(errno)); -+ break; -+ } -+ count += r; - } -- fclose(f); -+ close(fd); - } - - /** diff --git a/SOURCES/unbound-1.7.3-use-basic-lock.patch b/SOURCES/unbound-1.7.3-use-basic-lock.patch deleted file mode 100644 index d933bec..0000000 --- a/SOURCES/unbound-1.7.3-use-basic-lock.patch +++ /dev/null @@ -1,109 +0,0 @@ -diff --git a/util/log.c b/util/log.c -index 75a58f9..43dd572 100644 ---- a/util/log.c -+++ b/util/log.c -@@ -70,7 +70,7 @@ static int key_created = 0; - static ub_thread_key_type logkey; - #ifndef THREADS_DISABLED - /** pthread mutex to protect FILE* */ --static lock_quick_type log_lock; -+static lock_basic_type log_lock; - #endif - /** the identity of this executable/process */ - static const char* ident="unbound"; -@@ -90,18 +90,18 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - if(!key_created) { - key_created = 1; - ub_thread_key_create(&logkey, NULL); -- lock_quick_init(&log_lock); -+ lock_basic_init(&log_lock); - } -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - if(logfile - #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) - || logging_to_syslog - #endif - ) { -- lock_quick_unlock(&log_lock); /* verbose() needs the lock */ -+ lock_basic_unlock(&log_lock); /* verbose() needs the lock */ - verbose(VERB_QUERY, "switching log to %s", - use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - } - if(logfile && logfile != stderr) { - FILE* cl = logfile; -@@ -119,7 +119,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - * chroot and no longer be able to access dev/log and so on */ - openlog(ident, LOG_NDELAY, LOG_DAEMON); - logging_to_syslog = 1; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - #elif defined(UB_ON_WINDOWS) -@@ -128,13 +128,13 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - } - if(use_syslog) { - logging_to_syslog = 1; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - #endif /* HAVE_SYSLOG_H */ - if(!filename || !filename[0]) { - logfile = stderr; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - /* open the file for logging */ -@@ -143,7 +143,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - filename += strlen(chrootdir); - f = fopen(filename, "a"); - if(!f) { -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - log_err("Could not open logfile %s: %s", filename, - strerror(errno)); - return; -@@ -153,14 +153,14 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - setvbuf(f, NULL, (int)_IOLBF, 0); - #endif - logfile = f; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - } - - void log_file(FILE *f) - { -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - logfile = f; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - } - - void log_thread_set(int* num) -@@ -250,9 +250,9 @@ log_vmsg(int pri, const char* type, - return; - } - #endif /* HAVE_SYSLOG_H */ -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - if(!logfile) { -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - if(log_now) -@@ -279,7 +279,7 @@ log_vmsg(int pri, const char* type, - /* line buffering does not work on windows */ - fflush(logfile); - #endif -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - } - - /** diff --git a/SPECS/unbound.spec b/SPECS/unbound.spec index f67eb73..8a70f29 100644 --- a/SPECS/unbound.spec +++ b/SPECS/unbound.spec @@ -33,8 +33,8 @@ Summary: Validating, recursive, and caching DNS(SEC) resolver Name: unbound -Version: 1.7.3 -Release: 15%{?extra_version:.%{extra_version}}%{?dist} +Version: 1.13.1 +Release: 1%{?extra_version:.%{extra_version}}%{?dist} License: BSD Url: https://www.unbound.net/ Source: https://www.unbound.net/downloads/%{name}-%{version}%{?extra_version}.tar.gz @@ -55,21 +55,6 @@ Source15: unbound-anchor.timer Source16: unbound-munin.README Source17: unbound-anchor.service -Patch2: unbound-1.7.2-python3-devel.patch -Patch3: unbound-1.7.2-python3-pkgconfig.patch -Patch4: unbound-1.7.3-anchor-fallback.patch -Patch5: unbound-1.7.3-host-any.patch -Patch6: unbound-1.7.3-use-basic-lock.patch -Patch7: unbound-1.7.3-ipsec-hook.patch -Patch8: unbound-1.7.3-auth-callback.patch -Patch9: unbound-1.7.3-ksk-2010-revoked.patch -Patch10: unbound-1.7.3-DNS-over-TLS-memory-leak.patch -Patch11: unbound-1.7.3-amplifying-an-incoming-query.patch -Patch12: unbound-1.7.3-crypto-policy-non-compliance-openssl.patch -Patch13: unbound-1.7.3-additional-logging.patch -Patch14: unbound-1.7.3-security-hardening.patch -Patch15: unbound-1.7.3-symlink-traversal.patch - BuildRequires: gdb BuildRequires: gcc, make BuildRequires: byacc, flex, openssl-devel @@ -165,20 +150,6 @@ Python 3 modules and extensions for unbound %setup -qcn %{pkgname} pushd %{pkgname} -%patch2 -p1 -b .python3 -%patch3 -p1 -b .python3 -%patch4 -p1 -b .anchor-fallback -%patch5 -p1 -b .host-any -%patch6 -p1 -b .use-basic-lock -%patch7 -p1 -b .ipsec-hook -%patch8 -p1 -b .auth-callback -%patch9 -p1 -b .ksk-2010-revoked -%patch10 -p1 -b .DNS-over-TLS-memory-leak -%patch11 -p1 -b .amplifying-an-incoming-query -%patch12 -p1 -b .crypto-policy -%patch13 -p1 -b .additional-logging -%patch14 -p1 -b .security-hardening -%patch15 -p1 -b .symlink-traversal # only for snapshots # autoreconf -iv @@ -452,6 +423,9 @@ popd %verify(not md5 size mtime) %{_sharedstatedir}/%{name}/root.key %changelog +* Fri Mar 19 2021 Matthew Almond - 1.13.1-1 +- Simple test rebuild with a version bump. Goal is to test CentOS SIG PR workflow + * Tue Sep 01 2020 Anna Khaitovich - 1.7.3-15 - Fix SPEC file to not check md5 mtime and size of /var/lib/unbound/root.key - Resolves: rhbz#1714175