diff options
author | Cy Schubert <cy@FreeBSD.org> | 2019-12-31 15:50:41 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2019-12-31 15:50:41 +0000 |
commit | 0eefd3079a04edf4cf315403beb0344724567f42 (patch) | |
tree | ac77aee886bf3d3af45942d2573720d128c5688e /contrib/unbound/util | |
parent | 493c98c6d2b52d2066a913203e4cbcee5a6080c2 (diff) | |
parent | e2fe726866d062155f6b1aae749375475ef19191 (diff) | |
download | src-0eefd3079a04edf4cf315403beb0344724567f42.tar.gz src-0eefd3079a04edf4cf315403beb0344724567f42.zip |
Notes
Diffstat (limited to 'contrib/unbound/util')
23 files changed, 375 insertions, 126 deletions
diff --git a/contrib/unbound/util/config_file.c b/contrib/unbound/util/config_file.c index bdb55cbb0c02..fb6c33eacac9 100644 --- a/contrib/unbound/util/config_file.c +++ b/contrib/unbound/util/config_file.c @@ -255,6 +255,9 @@ config_create(void) cfg->neg_cache_size = 1 * 1024 * 1024; cfg->local_zones = NULL; cfg->local_zones_nodefault = NULL; +#ifdef USE_IPSET + cfg->local_zones_ipset = NULL; +#endif cfg->local_zones_disable_default = 0; cfg->local_data = NULL; cfg->local_zone_overrides = NULL; @@ -327,9 +330,13 @@ config_create(void) cfg->cachedb_backend = NULL; cfg->cachedb_secret = NULL; #endif +#ifdef USE_IPSET + cfg->ipset_name_v4 = NULL; + cfg->ipset_name_v6 = NULL; +#endif return cfg; error_exit: - config_delete(cfg); + config_delete(cfg); return NULL; } @@ -602,7 +609,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_STR("control-key-file:", control_key_file) else S_STR("control-cert-file:", control_cert_file) else S_STR("module-config:", module_conf) - else S_STR("python-script:", python_script) + else S_STRLIST("python-script:", python_script) else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check) #ifdef CLIENT_SUBNET /* Can't set max subnet prefix here, since that value is used when @@ -1054,7 +1061,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones) else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones) else O_DEC(opt, "max-udp-size", max_udp_size) - else O_STR(opt, "python-script", python_script) + else O_LST(opt, "python-script", python_script) else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check) else O_DEC(opt, "ip-ratelimit", ip_ratelimit) else O_DEC(opt, "ratelimit", ratelimit) @@ -1092,6 +1099,10 @@ config_get_option(struct config_file* cfg, const char* opt, else O_STR(opt, "backend", cachedb_backend) else O_STR(opt, "secret-seed", cachedb_secret) #endif +#ifdef USE_IPSET + else O_STR(opt, "name-v4", ipset_name_v4) + else O_STR(opt, "name-v6", ipset_name_v6) +#endif /* not here: * outgoing-permit, outgoing-avoid - have list of ports * local-zone - zones and nodefault variables @@ -1310,6 +1321,9 @@ config_delview(struct config_view* p) free(p->name); config_deldblstrlist(p->local_zones); config_delstrlist(p->local_zones_nodefault); +#ifdef USE_IPSET + config_delstrlist(p->local_zones_ipset); +#endif config_delstrlist(p->local_data); free(p); } @@ -1384,7 +1398,6 @@ config_delete(struct config_file* cfg) free(cfg->version); free(cfg->module_conf); free(cfg->outgoing_avail_ports); - free(cfg->python_script); config_delstrlist(cfg->caps_whitelist); config_delstrlist(cfg->private_address); config_delstrlist(cfg->private_domain); @@ -1400,6 +1413,9 @@ config_delete(struct config_file* cfg) free(cfg->val_nsec3_key_iterations); config_deldblstrlist(cfg->local_zones); config_delstrlist(cfg->local_zones_nodefault); +#ifdef USE_IPSET + config_delstrlist(cfg->local_zones_ipset); +#endif config_delstrlist(cfg->local_data); config_deltrplstrlist(cfg->local_zone_overrides); config_del_strarray(cfg->tagname, cfg->num_tags); @@ -1420,6 +1436,7 @@ config_delete(struct config_file* cfg) free(cfg->dnstap_version); config_deldblstrlist(cfg->ratelimit_for_domain); config_deldblstrlist(cfg->ratelimit_below_domain); + config_delstrlist(cfg->python_script); #ifdef USE_IPSECMOD free(cfg->ipsecmod_hook); config_delstrlist(cfg->ipsecmod_whitelist); @@ -1428,6 +1445,10 @@ config_delete(struct config_file* cfg) free(cfg->cachedb_backend); free(cfg->cachedb_secret); #endif +#ifdef USE_IPSET + free(cfg->ipset_name_v4); + free(cfg->ipset_name_v6); +#endif free(cfg); } @@ -1630,6 +1651,31 @@ cfg_strlist_insert(struct config_strlist** head, char* item) return 1; } +int +cfg_strlist_append_ex(struct config_strlist** head, char* item) +{ + struct config_strlist *s; + if(!item || !head) + return 0; + s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist)); + if(!s) + return 0; + s->str = item; + s->next = NULL; + + if (*head==NULL) { + *head = s; + } else { + struct config_strlist *last = *head; + while (last->next!=NULL) { + last = last->next; + } + last->next = s; + } + + return 1; +} + int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2) { @@ -2107,6 +2153,11 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val) if(strcmp(type, "nodefault")==0) { return cfg_strlist_insert(&cfg->local_zones_nodefault, strdup(name)); +#ifdef USE_IPSET + } else if(strcmp(type, "ipset")==0) { + return cfg_strlist_insert(&cfg->local_zones_ipset, + strdup(name)); +#endif } else { return cfg_str2list_insert(&cfg->local_zones, strdup(buf), strdup(type)); @@ -2381,3 +2432,4 @@ int options_remote_is_address(struct config_file* cfg) if(cfg->control_ifs.first->str[0] == 0) return 1; return (cfg->control_ifs.first->str[0] != '/'); } + diff --git a/contrib/unbound/util/config_file.h b/contrib/unbound/util/config_file.h index 3cffdbff9386..b3ef930a0f16 100644 --- a/contrib/unbound/util/config_file.h +++ b/contrib/unbound/util/config_file.h @@ -384,6 +384,10 @@ struct config_file { struct config_str2list* local_zones; /** local zones nodefault list */ struct config_strlist* local_zones_nodefault; +#ifdef USE_IPSET + /** local zones ipset list */ + struct config_strlist* local_zones_ipset; +#endif /** do not add any default local zone */ int local_zones_disable_default; /** local data RRs configured */ @@ -433,7 +437,7 @@ struct config_file { char* control_cert_file; /** Python script file */ - char* python_script; + struct config_strlist* python_script; /** Use systemd socket activation. */ int use_systemd; @@ -575,6 +579,12 @@ struct config_file { int redis_timeout; #endif #endif + + /* ipset module */ +#ifdef USE_IPSET + char* ipset_name_v4; + char* ipset_name_v6; +#endif }; /** from cfg username, after daemonize setup performed */ @@ -647,6 +657,10 @@ struct config_view { struct config_strlist* local_data; /** local zones nodefault list */ struct config_strlist* local_zones_nodefault; +#ifdef USE_IPSET + /** local zones ipset list */ + struct config_strlist* local_zones_ipset; +#endif /** Fallback to global local_zones when there is no match in the view * view specific tree. 1 for yes, 0 for no */ int isfirst; @@ -821,6 +835,14 @@ char* config_collate_cat(struct config_strlist* list); int cfg_strlist_append(struct config_strlist_head* list, char* item); /** + * Searches the end of a string list and appends the given text. + * @param head: pointer to strlist head variable. + * @param item: new item. malloced by caller. if NULL the insertion fails. + * @return true on success. + */ +int cfg_strlist_append_ex(struct config_strlist** head, char* item); + +/** * Find string in strlist. * @param head: pointer to strlist head variable. * @param item: the item to search for. @@ -1181,3 +1203,4 @@ void w_config_adjust_directory(struct config_file* cfg); extern int fake_dsa, fake_sha1; #endif /* UTIL_CONFIG_FILE_H */ + diff --git a/contrib/unbound/util/configlexer.lex b/contrib/unbound/util/configlexer.lex index 99311a6311a4..0afcb3ccefaa 100644 --- a/contrib/unbound/util/configlexer.lex +++ b/contrib/unbound/util/configlexer.lex @@ -113,8 +113,7 @@ static void config_start_include_glob(const char* filename) /* check for wildcards */ #ifdef HAVE_GLOB glob_t g; - size_t i; - int r, flags; + int i, r, flags; if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') && !strchr(filename, '{') && !strchr(filename, '~'))) { flags = 0 @@ -145,7 +144,7 @@ static void config_start_include_glob(const char* filename) return; } /* process files found, if any */ - for(i=0; i<(size_t)g.gl_pathc; i++) { + for(i=(int)g.gl_pathc-1; i>=0; i--) { config_start_include(g.gl_pathv[i]); } globfree(&g); @@ -484,6 +483,9 @@ secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) } redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) } redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) } redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } +ipset{COLON} { YDVAR(0, VAR_IPSET) } +name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) } +name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) } udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) } tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } diff --git a/contrib/unbound/util/configparser.y b/contrib/unbound/util/configparser.y index c7b916966e24..10227a2ff7ff 100644 --- a/contrib/unbound/util/configparser.y +++ b/contrib/unbound/util/configparser.y @@ -167,6 +167,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES %token VAR_TLS_SESSION_TICKET_KEYS +%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6 %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; @@ -174,7 +175,7 @@ toplevelvar: serverstart contents_server | stubstart contents_stub | forwardstart contents_forward | pythonstart contents_py | rcstart contents_rc | dtstart contents_dt | viewstart contents_view | dnscstart contents_dnsc | cachedbstart contents_cachedb | - authstart contents_auth + ipsetstart contents_ipset | authstart contents_auth ; /* server: declaration */ @@ -1784,13 +1785,14 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG && strcmp($3, "always_nxdomain")!=0 && strcmp($3, "noview")!=0 && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0 - && strcmp($3, "inform_redirect") != 0) { + && strcmp($3, "inform_redirect") != 0 + && strcmp($3, "ipset") != 0) { yyerror("local-zone type: expected static, deny, " "refuse, redirect, transparent, " "typetransparent, inform, inform_deny, " "inform_redirect, always_transparent, " "always_refuse, always_nxdomain, noview " - "or nodefault"); + ", nodefault or ipset"); free($2); free($3); } else if(strcmp($3, "nodefault")==0) { @@ -1798,6 +1800,13 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG local_zones_nodefault, $2)) fatal_exit("out of memory adding local-zone"); free($3); +#ifdef USE_IPSET + } else if(strcmp($3, "ipset")==0) { + if(!cfg_strlist_insert(&cfg_parser->cfg-> + local_zones_ipset, $2)) + fatal_exit("out of memory adding local-zone"); + free($3); +#endif } else { if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones, $2, $3)) @@ -2455,6 +2464,13 @@ view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG local_zones_nodefault, $2)) fatal_exit("out of memory adding local-zone"); free($3); +#ifdef USE_IPSET + } else if(strcmp($3, "ipset")==0) { + if(!cfg_strlist_insert(&cfg_parser->cfg->views-> + local_zones_ipset, $2)) + fatal_exit("out of memory adding local-zone"); + free($3); +#endif } else { if(!cfg_str2list_insert( &cfg_parser->cfg->views->local_zones, @@ -2722,8 +2738,8 @@ content_py: py_script py_script: VAR_PYTHON_SCRIPT STRING_ARG { OUTYY(("P(python-script:%s)\n", $2)); - free(cfg_parser->cfg->python_script); - cfg_parser->cfg->python_script = $2; + if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, $2)) + yyerror("out of memory"); } server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG { @@ -2959,6 +2975,45 @@ server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG } } ; + ipsetstart: VAR_IPSET + { + OUTYY(("\nP(ipset:)\n")); + } + ; + contents_ipset: contents_ipset content_ipset + | ; + content_ipset: ipset_name_v4 | ipset_name_v6 + ; + ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG + { + #ifdef USE_IPSET + OUTYY(("P(name-v4:%s)\n", $2)); + if(cfg_parser->cfg->ipset_name_v4) + yyerror("ipset name v4 override, there must be one " + "name for ip v4"); + free(cfg_parser->cfg->ipset_name_v4); + cfg_parser->cfg->ipset_name_v4 = $2; + #else + OUTYY(("P(Compiled without ipset, ignoring)\n")); + free($2); + #endif + } + ; + ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG + { + #ifdef USE_IPSET + OUTYY(("P(name-v6:%s)\n", $2)); + if(cfg_parser->cfg->ipset_name_v6) + yyerror("ipset name v6 override, there must be one " + "name for ip v6"); + free(cfg_parser->cfg->ipset_name_v6); + cfg_parser->cfg->ipset_name_v6 = $2; + #else + OUTYY(("P(Compiled without ipset, ignoring)\n")); + free($2); + #endif + } + ; %% /* parse helper routines could be here */ @@ -2978,3 +3033,5 @@ validate_respip_action(const char* action) "always_refuse or always_nxdomain"); } } + + diff --git a/contrib/unbound/util/data/dname.c b/contrib/unbound/util/data/dname.c index c7360f75f32a..9f25e1efe204 100644 --- a/contrib/unbound/util/data/dname.c +++ b/contrib/unbound/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) @@ -327,16 +329,26 @@ 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 */ dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *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/contrib/unbound/util/data/msgencode.c b/contrib/unbound/util/data/msgencode.c index 4c0a5550be13..a51a4b9b85d8 100644 --- a/contrib/unbound/util/data/msgencode.c +++ b/contrib/unbound/util/data/msgencode.c @@ -639,15 +639,37 @@ positive_answer(struct reply_info* rep, uint16_t qtype) { return 0; } -int -reply_info_encode(struct query_info* qinfo, struct reply_info* rep, - uint16_t id, uint16_t flags, sldns_buffer* buffer, time_t timenow, - struct regional* region, uint16_t udpsize, int dnssec) +static int +negative_answer(struct reply_info* rep) { + size_t i; + int ns_seen = 0; + if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN) + return 1; + if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR && + rep->an_numrrsets != 0) + return 0; /* positive */ + if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR && + FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN) + return 0; + for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++){ + if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_SOA) + return 1; + if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS) + ns_seen = 1; + } + if(ns_seen) return 0; /* could be referral, NS, but no SOA */ + return 1; +} + +int +reply_info_encode(struct query_info* qinfo, struct reply_info* rep, + uint16_t id, uint16_t flags, sldns_buffer* buffer, time_t timenow, + struct regional* region, uint16_t udpsize, int dnssec, int minimise) { uint16_t ancount=0, nscount=0, arcount=0; struct compress_tree_node* tree = 0; int r; - size_t rr_offset; + size_t rr_offset; sldns_buffer_clear(buffer); if(udpsize < sldns_buffer_limit(buffer)) @@ -663,7 +685,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, /* insert query section */ if(rep->qdcount) { - if((r=insert_query(qinfo, &tree, buffer, region)) != + if((r=insert_query(qinfo, &tree, buffer, region)) != RETVAL_OK) { if(r == RETVAL_TRUNC) { /* create truncated message */ @@ -707,8 +729,8 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, } /* insert answer section */ - if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer, - 0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype, + if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer, + 0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype, dnssec, rr_offset)) != RETVAL_OK) { if(r == RETVAL_TRUNC) { /* create truncated message */ @@ -722,9 +744,9 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, sldns_buffer_write_u16_at(buffer, 6, ancount); /* if response is positive answer, auth/add sections are not required */ - if( ! (MINIMAL_RESPONSES && positive_answer(rep, qinfo->qtype)) ) { + if( ! (minimise && positive_answer(rep, qinfo->qtype)) ) { /* insert auth section */ - if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer, + if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer, rep->an_numrrsets, timenow, region, &tree, LDNS_SECTION_AUTHORITY, qinfo->qtype, dnssec, rr_offset)) != RETVAL_OK) { @@ -739,20 +761,22 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, } sldns_buffer_write_u16_at(buffer, 8, nscount); - /* insert add section */ - if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer, - rep->an_numrrsets + rep->ns_numrrsets, timenow, region, - &tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype, - dnssec, rr_offset)) != RETVAL_OK) { - if(r == RETVAL_TRUNC) { - /* no need to set TC bit, this is the additional */ - sldns_buffer_write_u16_at(buffer, 10, arcount); - sldns_buffer_flip(buffer); - return 1; + if(! (minimise && negative_answer(rep))) { + /* insert add section */ + if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer, + rep->an_numrrsets + rep->ns_numrrsets, timenow, region, + &tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype, + dnssec, rr_offset)) != RETVAL_OK) { + if(r == RETVAL_TRUNC) { + /* no need to set TC bit, this is the additional */ + sldns_buffer_write_u16_at(buffer, 10, arcount); + sldns_buffer_flip(buffer); + return 1; + } + return 0; } - return 0; + sldns_buffer_write_u16_at(buffer, 10, arcount); } - sldns_buffer_write_u16_at(buffer, 10, arcount); } sldns_buffer_flip(buffer); return 1; @@ -763,7 +787,7 @@ calc_edns_field_size(struct edns_data* edns) { size_t rdatalen = 0; struct edns_option* opt; - if(!edns || !edns->edns_present) + if(!edns || !edns->edns_present) return 0; for(opt = edns->opt_list; opt; opt = opt->next) { rdatalen += 4 + opt->opt_len; @@ -850,7 +874,7 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, } if(!reply_info_encode(qinf, rep, id, flags, pkt, timenow, region, - udpsize, dnssec)) { + udpsize, dnssec, MINIMAL_RESPONSES)) { log_err("reply encode: out of memory"); return 0; } diff --git a/contrib/unbound/util/data/msgencode.h b/contrib/unbound/util/data/msgencode.h index eea129d98d59..30dc515cbe59 100644 --- a/contrib/unbound/util/data/msgencode.h +++ b/contrib/unbound/util/data/msgencode.h @@ -85,12 +85,14 @@ int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, * @param region: to store temporary data in. * @param udpsize: size of the answer, 512, from EDNS, or 64k for TCP. * @param dnssec: if 0 DNSSEC records are omitted from the answer. + * @param minimise: if true, the answer is a minimal response, with + * authority and additional removed if possible. * @return: nonzero is success, or * 0 on error: malloc failure (no log_err has been done). */ int reply_info_encode(struct query_info* qinfo, struct reply_info* rep, uint16_t id, uint16_t flags, struct sldns_buffer* buffer, time_t timenow, - struct regional* region, uint16_t udpsize, int dnssec); + struct regional* region, uint16_t udpsize, int dnssec, int minimise); /** * Encode query packet. Assumes the buffer is large enough. diff --git a/contrib/unbound/util/data/msgparse.c b/contrib/unbound/util/data/msgparse.c index 13cad8a26630..fb312370366d 100644 --- a/contrib/unbound/util/data/msgparse.c +++ b/contrib/unbound/util/data/msgparse.c @@ -1061,18 +1061,18 @@ parse_edns_from_pkt(sldns_buffer* pkt, struct edns_data* edns, size_t rdata_len; uint8_t* rdata_ptr; log_assert(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) == 1); + memset(edns, 0, sizeof(*edns)); if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 || LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) { if(!skip_pkt_rrs(pkt, ((int)LDNS_ANCOUNT(sldns_buffer_begin(pkt)))+ ((int)LDNS_NSCOUNT(sldns_buffer_begin(pkt))))) - return 0; + return LDNS_RCODE_FORMERR; } /* check edns section is present */ if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) { return LDNS_RCODE_FORMERR; } if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) == 0) { - memset(edns, 0, sizeof(*edns)); edns->udp_size = 512; return 0; } diff --git a/contrib/unbound/util/data/msgreply.c b/contrib/unbound/util/data/msgreply.c index 32aec4bf4c95..4320f312d6f3 100644 --- a/contrib/unbound/util/data/msgreply.c +++ b/contrib/unbound/util/data/msgreply.c @@ -243,10 +243,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++; @@ -819,7 +819,7 @@ log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep) sldns_buffer* buf = sldns_buffer_new(65535); struct regional* region = regional_create(); if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0, - region, 65535, 1)) { + region, 65535, 1, 0)) { log_info("%s: log_dns_msg: out of memory", str); } else { char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf), diff --git a/contrib/unbound/util/fptr_wlist.c b/contrib/unbound/util/fptr_wlist.c index 94d23fa3a32a..f5da501de19b 100644 --- a/contrib/unbound/util/fptr_wlist.c +++ b/contrib/unbound/util/fptr_wlist.c @@ -90,6 +90,9 @@ #ifdef CLIENT_SUBNET #include "edns-subnet/subnetmod.h" #endif +#ifdef USE_IPSET +#include "ipset/ipset.h" +#endif int fptr_whitelist_comm_point(comm_point_callback_type *fptr) @@ -358,8 +361,8 @@ fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq)) } int -fptr_whitelist_modenv_detect_cycle(int (*fptr)( - struct module_qstate* qstate, struct query_info* qinfo, +fptr_whitelist_modenv_detect_cycle(int (*fptr)( + struct module_qstate* qstate, struct query_info* qinfo, uint16_t flags, int prime, int valrec)) { if(fptr == &mesh_detect_cycle) return 1; @@ -385,6 +388,9 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)) #ifdef CLIENT_SUBNET else if(fptr == &subnetmod_init) return 1; #endif +#ifdef USE_IPSET + else if(fptr == &ipset_init) return 1; +#endif return 0; } @@ -407,6 +413,9 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)) #ifdef CLIENT_SUBNET else if(fptr == &subnetmod_deinit) return 1; #endif +#ifdef USE_IPSET + else if(fptr == &ipset_deinit) return 1; +#endif return 0; } @@ -430,6 +439,9 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate, #ifdef CLIENT_SUBNET else if(fptr == &subnetmod_operate) return 1; #endif +#ifdef USE_IPSET + else if(fptr == &ipset_operate) return 1; +#endif return 0; } @@ -453,6 +465,9 @@ fptr_whitelist_mod_inform_super(void (*fptr)( #ifdef CLIENT_SUBNET else if(fptr == &subnetmod_inform_super) return 1; #endif +#ifdef USE_IPSET + else if(fptr == &ipset_inform_super) return 1; +#endif return 0; } @@ -476,6 +491,9 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate, #ifdef CLIENT_SUBNET else if(fptr == &subnetmod_clear) return 1; #endif +#ifdef USE_IPSET + else if(fptr == &ipset_clear) return 1; +#endif return 0; } @@ -498,6 +516,9 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id)) #ifdef CLIENT_SUBNET else if(fptr == &subnetmod_get_mem) return 1; #endif +#ifdef USE_IPSET + else if(fptr == &ipset_get_mem) return 1; +#endif return 0; } @@ -597,3 +618,4 @@ int fptr_whitelist_inplace_cb_query_response( #endif return 0; } + diff --git a/contrib/unbound/util/iana_ports.inc b/contrib/unbound/util/iana_ports.inc index aa972a67bd5d..3e6f3e6be617 100644 --- a/contrib/unbound/util/iana_ports.inc +++ b/contrib/unbound/util/iana_ports.inc @@ -960,8 +960,6 @@ 1298, 1299, 1300, -1301, -1302, 1303, 1304, 1305, @@ -1848,7 +1846,6 @@ 2197, 2198, 2199, -2200, 2201, 2202, 2203, diff --git a/contrib/unbound/util/log.c b/contrib/unbound/util/log.c index 318ff1d79107..8499d8c0a8a7 100644 --- a/contrib/unbound/util/log.c +++ b/contrib/unbound/util/log.c @@ -61,7 +61,7 @@ #endif /* default verbosity */ -enum verbosity_value verbosity = 0; +enum verbosity_value verbosity = NO_VERBOSE; /** the file logged to. */ static FILE* logfile = 0; /** if key has been created */ @@ -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"; @@ -88,18 +88,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; @@ -115,9 +115,11 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) if(use_syslog) { /* do not delay opening until first write, because we may * chroot and no longer be able to access dev/log and so on */ - openlog(ident, LOG_NDELAY, LOG_DAEMON); + /* the facility is LOG_DAEMON by default, but + * --with-syslog-facility=LOCAL[0-7] can override it */ + openlog(ident, LOG_NDELAY, UB_SYSLOG_FACILITY); logging_to_syslog = 1; - lock_quick_unlock(&log_lock); + lock_basic_unlock(&log_lock); return; } #elif defined(UB_ON_WINDOWS) @@ -126,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 */ @@ -141,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; @@ -151,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) @@ -243,9 +245,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; } now = (time_t)time(NULL); @@ -270,7 +272,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/contrib/unbound/util/mini_event.c b/contrib/unbound/util/mini_event.c index faadf1a23c8d..661d88d2e6f6 100644 --- a/contrib/unbound/util/mini_event.c +++ b/contrib/unbound/util/mini_event.c @@ -313,7 +313,7 @@ int event_add(struct event* ev, struct timeval* tv) struct timeval *now = ev->ev_base->time_tv; ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec; ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec; - while(ev->ev_timeout.tv_usec > 1000000) { + while(ev->ev_timeout.tv_usec >= 1000000) { ev->ev_timeout.tv_usec -= 1000000; ev->ev_timeout.tv_sec++; } diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c index 13bcdf8085bf..9747b5d55a78 100644 --- a/contrib/unbound/util/net_help.c +++ b/contrib/unbound/util/net_help.c @@ -698,10 +698,19 @@ void log_crypto_err(const char* str) { #ifdef HAVE_SSL + log_crypto_err_code(str, ERR_get_error()); +#else + (void)str; +#endif /* HAVE_SSL */ +} + +void log_crypto_err_code(const char* str, unsigned long err) +{ +#ifdef HAVE_SSL /* error:[error code]:[library name]:[function name]:[reason string] */ char buf[128]; unsigned long e; - ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); + ERR_error_string_n(err, buf, sizeof(buf)); log_err("%s crypto %s", str, buf); while( (e=ERR_get_error()) ) { ERR_error_string_n(e, buf, sizeof(buf)); @@ -709,6 +718,7 @@ log_crypto_err(const char* str) } #else (void)str; + (void)err; #endif /* HAVE_SSL */ } @@ -744,6 +754,14 @@ listen_sslctx_setup(void* ctxt) return 0; } #endif +#if defined(SSL_OP_NO_RENEGOTIATION) + /* disable client renegotiation */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & + SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) { + log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION"); + return 0; + } +#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")) @@ -962,6 +980,14 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert) SSL_CTX_free(ctx); return NULL; } +#if defined(SSL_OP_NO_RENEGOTIATION) + /* disable client renegotiation */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & + SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) { + log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION"); + return 0; + } +#endif if(key && key[0]) { if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { log_err("error in client certificate %s", pem); @@ -1019,7 +1045,7 @@ void* incoming_ssl_fd(void* sslctx, int fd) return NULL; } SSL_set_accept_state(ssl); - (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY); if(!SSL_set_fd(ssl, fd)) { log_crypto_err("could not SSL_set_fd"); SSL_free(ssl); @@ -1041,7 +1067,7 @@ void* outgoing_ssl_fd(void* sslctx, int fd) return NULL; } SSL_set_connect_state(ssl); - (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY); if(!SSL_set_fd(ssl, fd)) { log_crypto_err("could not SSL_set_fd"); SSL_free(ssl); @@ -1197,10 +1223,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed"); return -1; } +#ifndef HMAC_INIT_EX_RETURNS_VOID if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) { verbose(VERB_CLIENT, "HMAC_Init_ex failed"); return -1; } +#else + HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL); +#endif return 1; } else if (enc == 0) { /* decrypt */ @@ -1217,10 +1247,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name return 0; } +#ifndef HMAC_INIT_EX_RETURNS_VOID if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) { verbose(VERB_CLIENT, "HMAC_Init_ex failed"); return -1; } +#else + HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL); +#endif if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) { log_err("EVP_DecryptInit_ex failed"); return -1; diff --git a/contrib/unbound/util/net_help.h b/contrib/unbound/util/net_help.h index 0b197fbdd6e7..79e2a834931a 100644 --- a/contrib/unbound/util/net_help.h +++ b/contrib/unbound/util/net_help.h @@ -379,6 +379,13 @@ void sock_list_merge(struct sock_list** list, struct regional* region, void log_crypto_err(const char* str); /** + * Log libcrypto error from errcode with descriptive string, calls log_err. + * @param str: what failed. + * @param err: error code from ERR_get_error. + */ +void log_crypto_err_code(const char* str, unsigned long err); + +/** * Set SSL_OP_NOxxx options on SSL context to disable bad crypto * @param ctxt: SSL_CTX* * @return false on failure. diff --git a/contrib/unbound/util/netevent.c b/contrib/unbound/util/netevent.c index 9e2ba92b5fdf..980bb8bea972 100644 --- a/contrib/unbound/util/netevent.c +++ b/contrib/unbound/util/netevent.c @@ -1001,7 +1001,7 @@ tcp_callback_writer(struct comm_point* c) tcp_req_info_handle_writedone(c->tcp_req_info); } else { comm_point_stop_listening(c); - comm_point_start_listening(c, -1, -1); + comm_point_start_listening(c, -1, c->tcp_timeout_msec); } } @@ -1052,6 +1052,35 @@ log_cert(unsigned level, const char* str, X509* cert) } #endif /* HAVE_SSL */ +#ifdef HAVE_SSL +/** true if the ssl handshake error has to be squelched from the logs */ +static int +squelch_err_ssl_handshake(unsigned long err) +{ + if(verbosity >= VERB_QUERY) + return 0; /* only squelch on low verbosity */ + /* this is very specific, we could filter on ERR_GET_REASON() + * (the third element in ERR_PACK) */ + if(err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTPS_PROXY_REQUEST) || + err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTP_REQUEST) || + err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER) || + err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_READ_BYTES, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE) +#ifdef SSL_F_TLS_POST_PROCESS_CLIENT_HELLO + || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER) +#endif +#ifdef SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO + || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL) + || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL) +# ifdef SSL_R_VERSION_TOO_LOW + || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_VERSION_TOO_LOW) +# endif +#endif + ) + return 1; + return 0; +} +#endif /* HAVE_SSL */ + /** continue ssl handshake */ #ifdef HAVE_SSL static int @@ -1096,9 +1125,12 @@ ssl_handshake(struct comm_point* c) strerror(errno)); return 0; } else { - log_crypto_err("ssl handshake failed"); - log_addr(1, "ssl handshake failed", &c->repinfo.addr, - c->repinfo.addrlen); + unsigned long err = ERR_get_error(); + if(!squelch_err_ssl_handshake(err)) { + log_crypto_err_code("ssl handshake failed", err); + log_addr(VERB_OPS, "ssl handshake failed", &c->repinfo.addr, + c->repinfo.addrlen); + } return 0; } } @@ -1277,7 +1309,7 @@ ssl_handle_write(struct comm_point* c) return 1; } /* ignore return, if fails we may simply block */ - (void)SSL_set_mode(c->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); + (void)SSL_set_mode(c->ssl, (long)SSL_MODE_ENABLE_PARTIAL_WRITE); if(c->tcp_byte_count < sizeof(uint16_t)) { uint16_t len = htons(sldns_buffer_limit(c->buffer)); ERR_clear_error(); @@ -3159,7 +3191,7 @@ comm_point_drop_reply(struct comm_reply* repinfo) { if(!repinfo) return; - log_assert(repinfo && repinfo->c); + log_assert(repinfo->c); log_assert(repinfo->c->type != comm_tcp_accept); if(repinfo->c->type == comm_udp) return; diff --git a/contrib/unbound/util/random.c b/contrib/unbound/util/random.c index 8332960b4d0c..bb564f2f99aa 100644 --- a/contrib/unbound/util/random.c +++ b/contrib/unbound/util/random.c @@ -79,15 +79,8 @@ #define MAX_VALUE 0x7fffffff #if defined(HAVE_SSL) -void -ub_systemseed(unsigned int ATTR_UNUSED(seed)) -{ - /* arc4random_uniform does not need seeds, it gets kernel entropy */ -} - 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) { @@ -119,12 +112,7 @@ struct ub_randstate { int ready; }; -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 +128,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; @@ -157,17 +147,7 @@ struct ub_randstate { int seeded; }; -void ub_systemseed(unsigned int ATTR_UNUSED(seed)) -{ -/** - * We seed on init and not here, as we need the ctx to re-seed. - * This also means that re-seeding is not supported. - */ - 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 +163,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/contrib/unbound/util/random.h b/contrib/unbound/util/random.h index a05a994a3d52..b257793a4449 100644 --- a/contrib/unbound/util/random.h +++ b/contrib/unbound/util/random.h @@ -48,24 +48,13 @@ struct ub_randstate; /** - * Initialize the system randomness. Obtains entropy from the system - * before a chroot or privilege makes it unavailable. - * You do not have to call this, otherwise ub_initstate does so. - * @param seed: seed value to create state (if no good entropy is found). - */ -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/contrib/unbound/util/regional.c b/contrib/unbound/util/regional.c index 899a54edbddd..ff36d0e21241 100644 --- a/contrib/unbound/util/regional.c +++ b/contrib/unbound/util/regional.c @@ -84,6 +84,7 @@ struct regional* regional_create_custom(size_t size) { struct regional* r = (struct regional*)malloc(size); + size = ALIGN_UP(size, ALIGNMENT); log_assert(sizeof(struct regional) <= size); if(!r) return NULL; r->first_size = size; @@ -120,8 +121,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/contrib/unbound/util/shm_side/shm_main.c b/contrib/unbound/util/shm_side/shm_main.c index a783c099b5a4..46a71510fea3 100644 --- a/contrib/unbound/util/shm_side/shm_main.c +++ b/contrib/unbound/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) { @@ -223,8 +223,10 @@ void shm_main_run(struct worker *worker) struct ub_stats_info *stat_info; int offset; +#ifndef S_SPLINT_S verbose(VERB_DETAIL, "SHM run - worker [%d] - daemon [%p] - timenow(%u) - timeboot(%u)", worker->thread_num, worker->daemon, (unsigned)worker->env.now_tv->tv_sec, (unsigned)worker->daemon->time_boot.tv_sec); +#endif offset = worker->thread_num + 1; stat_total = worker->daemon->shm_info->ptr_arr; @@ -240,9 +242,11 @@ void shm_main_run(struct worker *worker) memset(stat_total, 0, sizeof(struct ub_stats_info)); /* Point to data into SHM */ +#ifndef S_SPLINT_S shm_stat = worker->daemon->shm_info->ptr_ctl; shm_stat->time.now_sec = (long long)worker->env.now_tv->tv_sec; shm_stat->time.now_usec = (long long)worker->env.now_tv->tv_usec; +#endif stat_timeval_subtract(&shm_stat->time.up_sec, &shm_stat->time.up_usec, worker->env.now_tv, &worker->daemon->time_boot); stat_timeval_subtract(&shm_stat->time.elapsed_sec, &shm_stat->time.elapsed_usec, worker->env.now_tv, &worker->daemon->time_last_stat); diff --git a/contrib/unbound/util/ub_event.c b/contrib/unbound/util/ub_event.c index e097fbc40158..9af476ad4084 100644 --- a/contrib/unbound/util/ub_event.c +++ b/contrib/unbound/util/ub_event.c @@ -458,7 +458,9 @@ void ub_comm_base_now(struct comm_base* cb) if(gettimeofday(tv, NULL) < 0) { log_err("gettimeofday: %s", strerror(errno)); } +#ifndef S_SPLINT_S *tt = tv->tv_sec; +#endif #endif /* USE_MINI_EVENT */ } diff --git a/contrib/unbound/util/ub_event_pluggable.c b/contrib/unbound/util/ub_event_pluggable.c index 4a9451263b7c..235bba6ba797 100644 --- a/contrib/unbound/util/ub_event_pluggable.c +++ b/contrib/unbound/util/ub_event_pluggable.c @@ -453,7 +453,7 @@ ub_get_event_sys(struct ub_event_base* ub_base, const char** n, const char** s, * ub_base is guaranteed to exist and to be the default * event base. */ - assert(b); + assert(b != NULL); *n = "pluggable-event"; *s = event_get_version(); # if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP) @@ -687,6 +687,8 @@ void ub_comm_base_now(struct comm_base* cb) if(gettimeofday(tv, NULL) < 0) { log_err("gettimeofday: %s", strerror(errno)); } +#ifndef S_SPLINT_S *tt = tv->tv_sec; +#endif } diff --git a/contrib/unbound/util/winsock_event.c b/contrib/unbound/util/winsock_event.c index 63d98796d19f..de6c28ecb08e 100644 --- a/contrib/unbound/util/winsock_event.c +++ b/contrib/unbound/util/winsock_event.c @@ -558,7 +558,7 @@ int event_add(struct event *ev, struct timeval *tv) struct timeval *now = ev->ev_base->time_tv; ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec; ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec; - while(ev->ev_timeout.tv_usec > 1000000) { + while(ev->ev_timeout.tv_usec >= 1000000) { ev->ev_timeout.tv_usec -= 1000000; ev->ev_timeout.tv_sec++; } |