import unbound-1.7.3-15.el8
This commit is contained in:
parent
5e15f0d58d
commit
a79f3688e2
553
SOURCES/unbound-1.7.3-additional-logging.patch
Normal file
553
SOURCES/unbound-1.7.3-additional-logging.patch
Normal file
@ -0,0 +1,553 @@
|
||||
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<yes or no>
|
||||
+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<yes or no>
|
||||
+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<yes or no>
|
||||
+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<filename>
|
||||
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;
|
@ -0,0 +1,13 @@
|
||||
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
|
||||
|
677
SOURCES/unbound-1.7.3-security-hardening.patch
Normal file
677
SOURCES/unbound-1.7.3-security-hardening.patch
Normal file
@ -0,0 +1,677 @@
|
||||
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; i<data->count; i++)
|
||||
+ for(i=0; i<data->count; 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<num; i++) {
|
||||
a[i] = ub_random(r);
|
||||
unit_assert(a[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;
|
||||
}
|
||||
|
43
SOURCES/unbound-1.7.3-symlink-traversal.patch
Normal file
43
SOURCES/unbound-1.7.3-symlink-traversal.patch
Normal file
@ -0,0 +1,43 @@
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
@ -34,7 +34,7 @@
|
||||
Summary: Validating, recursive, and caching DNS(SEC) resolver
|
||||
Name: unbound
|
||||
Version: 1.7.3
|
||||
Release: 14%{?extra_version:.%{extra_version}}%{?dist}
|
||||
Release: 15%{?extra_version:.%{extra_version}}%{?dist}
|
||||
License: BSD
|
||||
Url: https://www.unbound.net/
|
||||
Source: https://www.unbound.net/downloads/%{name}-%{version}%{?extra_version}.tar.gz
|
||||
@ -65,9 +65,14 @@ 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: flex, openssl-devel
|
||||
BuildRequires: byacc, flex, openssl-devel
|
||||
BuildRequires: libevent-devel expat-devel
|
||||
BuildRequires: pkgconfig
|
||||
%if 0%{with_python2}
|
||||
@ -170,6 +175,10 @@ pushd %{pkgname}
|
||||
%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
|
||||
@ -439,8 +448,22 @@ popd
|
||||
%attr(0644,unbound,unbound) %config %{_sharedstatedir}/%{name}/root.key
|
||||
# just left for backwards compat with user changed unbound.conf files - format is different!
|
||||
%attr(0644,root,root) %config %{_sysconfdir}/%{name}/root.key
|
||||
# modification of root.key is maintained by unbound-achor.service and is intentional, so let rpm know
|
||||
%verify(not md5 size mtime) %{_sharedstatedir}/%{name}/root.key
|
||||
|
||||
%changelog
|
||||
* Tue Sep 01 2020 Anna Khaitovich <akhaitov@redhat.com> - 1.7.3-15
|
||||
- Fix SPEC file to not check md5 mtime and size of /var/lib/unbound/root.key
|
||||
- Resolves: rhbz#1714175
|
||||
- Use system-wide crypto policy setting (PROFILE=SYSTEM) instead of custom setting
|
||||
- Resolves: rhbz#1842837
|
||||
- Enable additional logging in unbound
|
||||
- Resolves: rhbz#1850460
|
||||
- security hardening from x41 report
|
||||
- Resolves: rhbz#1859933
|
||||
- symbolic link traversal when writing PID file
|
||||
- Resolves: rhbz#1899058
|
||||
|
||||
* Thu May 28 2020 Anna Khaitovich <akhaitov@redhat.com> - 1.7.3-14
|
||||
- Fix unbound-1.7.3-amplifying-an-incoming-query.patch patch
|
||||
- Resolves: rhbz#1839178 (CVE-2020-12662)
|
||||
|
Loading…
Reference in New Issue
Block a user