diff --git a/config.h.in b/config.h.in index 04356f3..3b06bfa 100644 --- a/config.h.in +++ b/config.h.in @@ -666,6 +666,9 @@ /* Shared data */ #undef SHARE_DIR +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + /* The size of `time_t', as computed by sizeof. */ #undef SIZEOF_TIME_T diff --git a/configure.ac b/configure.ac index c5e0c7b..1bff4ed 100644 --- a/configure.ac +++ b/configure.ac @@ -371,6 +371,7 @@ AC_INCLUDES_DEFAULT # endif #endif ]) +AC_CHECK_SIZEOF(size_t) # add option to disable the evil rpath ACX_ARG_RPATH diff --git a/contrib/create_unbound_ad_servers.sh b/contrib/create_unbound_ad_servers.sh index d31f078..49fdbff 100644 --- a/contrib/create_unbound_ad_servers.sh +++ b/contrib/create_unbound_ad_servers.sh @@ -9,12 +9,13 @@ # Variables dst_dir="/etc/opt/csw/unbound" work_dir="/tmp" -list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" +list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" # OS commands CAT=`which cat` ECHO=`which echo` WGET=`which wget` +TR=`which tr` # Check Wget installed if [ ! -f $WGET ]; then @@ -22,8 +23,10 @@ if [ ! -f $WGET ]; then exit 1 fi +# remove special characters with tr to protect unbound.conf $WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \ $CAT $work_dir/yoyo_ad_servers | \ +$TR -d '";$\\' | \ while read line ; \ do \ $ECHO "local-zone: \"$line\" redirect" ;\ @@ -36,4 +39,4 @@ echo "Done." # the unbound_ad_servers file: # # include: $dst_dir/unbound_ad_servers -# \ No newline at end of file +# diff --git a/daemon/daemon.c b/daemon/daemon.c index 6820e11..1b4f329 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -426,9 +426,7 @@ daemon_create_workers(struct daemon* daemon) int* shufport; log_assert(daemon && daemon->cfg); if(!daemon->rand) { - unsigned int seed = (unsigned int)time(NULL) ^ - (unsigned int)getpid() ^ 0x438; - daemon->rand = ub_initstate(seed, NULL); + daemon->rand = ub_initstate(NULL); if(!daemon->rand) fatal_exit("could not init random generator"); hash_set_raninit((uint32_t)ub_random(daemon->rand)); diff --git a/daemon/worker.c b/daemon/worker.c index 3acecc1..8354010 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1629,18 +1629,14 @@ worker_create(struct daemon* daemon, int id, int* ports, int n) return NULL; } /* create random state here to avoid locking trouble in RAND_bytes */ - seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ - (((unsigned int)worker->thread_num)<<17); - /* shift thread_num so it does not match out pid bits */ - if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) { - seed = 0; + if(!(worker->rndstate = ub_initstate(daemon->rand))) { log_err("could not init random numbers."); tube_delete(worker->cmd); free(worker->ports); free(worker); return NULL; } - seed = 0; + explicit_bzero(&seed, sizeof(seed)); #ifdef USE_DNSTAP if(daemon->cfg->dnstap) { log_assert(daemon->dtenv != NULL); diff --git a/dns64/dns64.c b/dns64/dns64.c index 7889d72..300202c 100644 --- a/dns64/dns64.c +++ b/dns64/dns64.c @@ -782,6 +782,16 @@ dns64_inform_super(struct module_qstate* qstate, int id, * Signal that the sub-query is finished, no matter whether we are * successful or not. This lets the state machine terminate. */ + if(!super->minfo[id]) { + super->minfo[id] = (enum dns64_qstate *)regional_alloc(super->region, + sizeof(*(super->minfo[id]))); + if(!super->minfo[id]) { + log_err("out of memory"); + super->return_rcode = LDNS_RCODE_SERVFAIL; + super->return_msg = NULL; + return; + } + } super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED; /* If there is no successful answer, we're done. */ diff --git a/dnscrypt/dnscrypt.c b/dnscrypt/dnscrypt.c index 3545d3d..7dd2ce5 100644 --- a/dnscrypt/dnscrypt.c +++ b/dnscrypt/dnscrypt.c @@ -732,6 +732,11 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg) ); continue; } + if((unsigned)strlen(dnscenv->provider_name) >= (unsigned)0xffff0000) { + /* guard against integer overflow in rrlen calculation */ + verbose(VERB_OPS, "cert #%" PRIu32 " is too long", serial); + continue; + } rrlen = strlen(dnscenv->provider_name) + strlen(ttl_class_type) + 4 * sizeof(struct SignedCert) + // worst case scenario diff --git a/doc/Changelog b/doc/Changelog index bb74461..4cb080e 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,55 @@ +3 December 2019: Wouter + - Fix Assert Causing DoS in synth_cname(), + reported by X41 D-Sec. + - Fix Assert Causing DoS in dname_pkt_copy(), + reported by X41 D-Sec. + - Fix OOB Read in sldns_wire2str_dname_scan(), + reported by X41 D-Sec. + - Fix Out of Bounds Write in sldns_str2wire_str_buf(), + reported by X41 D-Sec. + - Fix Out of Bounds Write in sldns_b64_pton(), + fixed by check in sldns_str2wire_int16_data_buf(), + reported by X41 D-Sec. + - Fix Insufficient Handling of Compressed Names in dname_pkt_copy(), + reported by X41 D-Sec. + - Fix Out of Bound Write Compressed Names in rdata_copy(), + reported by X41 D-Sec. + - Fix Hang in sldns_wire2str_pkt_scan(), + reported by X41 D-Sec. + +20 November 2019: Wouter + - Fix Out of Bounds Read in rrinternal_get_owner(), + reported by X41 D-Sec. + - Fix Race Condition in autr_tp_create(), + reported by X41 D-Sec. + - Fix Shared Memory World Writeable, + reported by X41 D-Sec. + - Adjust unbound-control to make stats_shm a read only operation. + - Fix Weak Entropy Used For Nettle, + reported by X41 D-Sec. + - Fix Randomness Error not Handled Properly, + reported by X41 D-Sec. + - Fix Out-of-Bounds Read in dname_valid(), + reported by X41 D-Sec. + - Fix Config Injection in create_unbound_ad_servers.sh, + reported by X41 D-Sec. + +19 November 2019: Wouter + - Fix Integer Overflow in Regional Allocator, + reported by X41 D-Sec. + - Fix Unchecked NULL Pointer in dns64_inform_super() + and ipsecmod_new(), reported by X41 D-Sec. + - Fix Out-of-bounds Read in rr_comment_dnskey(), + reported by X41 D-Sec. + - Fix Integer Overflows in Size Calculations, + reported by X41 D-Sec. + - Fix Integer Overflow to Buffer Overflow in + sldns_str2wire_dname_buf_origin(), reported by X41 D-Sec. + - Fix Out of Bounds Read in sldns_str2wire_dname(), + reported by X41 D-Sec. + - Fix Out of Bounds Write in sldns_bget_token_par(), + reported by X41 D-Sec. + 30 November 2018: Wouter - log-tag-queryreply: yes in unbound.conf tags the log-queries and log-replies in the log file for easier log filter maintenance. diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c index 3572f12..1422a62 100644 --- a/ipsecmod/ipsecmod.c +++ b/ipsecmod/ipsecmod.c @@ -103,11 +103,11 @@ ipsecmod_new(struct module_qstate* qstate, int id) { struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)regional_alloc( qstate->region, sizeof(struct ipsecmod_qstate)); - memset(iq, 0, sizeof(*iq)); qstate->minfo[id] = iq; if(!iq) return 0; /* Initialise it. */ + memset(iq, 0, sizeof(*iq)); iq->enabled = qstate->env->cfg->ipsecmod_enabled; iq->is_whitelisted = ipsecmod_domain_is_whitelisted( (struct ipsecmod_env*)qstate->env->modinfo[id], qstate->qinfo.qname, diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c index 8230d17..942c3d5 100644 --- a/iterator/iter_scrub.c +++ b/iterator/iter_scrub.c @@ -231,6 +231,10 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset, size_t dtarglen; if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt)) return 0; + if(qnamelen <= dname_rrset->dname_len) + return 0; + if(qnamelen == 0) + return 0; log_assert(qnamelen > dname_rrset->dname_len); /* DNAME from com. to net. with qname example.com. -> example.net. */ /* so: \3com\0 to \3net\0 and qname \7example\3com\0 */ diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index 275e8d2..a8979c2 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -83,7 +83,6 @@ static struct ub_ctx* ub_ctx_create_nopipe(void) { struct ub_ctx* ctx; - unsigned int seed; #ifdef USE_WINSOCK int r; WSADATA wsa_data; @@ -107,15 +106,12 @@ static struct ub_ctx* ub_ctx_create_nopipe(void) return NULL; } alloc_init(&ctx->superalloc, NULL, 0); - seed = (unsigned int)time(NULL) ^ (unsigned int)getpid(); - if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) { - seed = 0; + if(!(ctx->seed_rnd = ub_initstate(NULL))) { ub_randfree(ctx->seed_rnd); free(ctx); errno = ENOMEM; return NULL; } - seed = 0; lock_basic_init(&ctx->qqpipe_lock); lock_basic_init(&ctx->rrpipe_lock); lock_basic_init(&ctx->cfglock); diff --git a/libunbound/libworker.c b/libunbound/libworker.c index 3dcaa78..07a08c6 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -122,7 +122,6 @@ libworker_delete_event(struct libworker* w) static struct libworker* libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) { - unsigned int seed; struct libworker* w = (struct libworker*)calloc(1, sizeof(*w)); struct config_file* cfg = ctx->env->cfg; int* ports; @@ -177,17 +176,13 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) } w->env->worker = (struct worker*)w; w->env->probe_timer = NULL; - seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ - (((unsigned int)w->thread_num)<<17); - seed ^= (unsigned int)w->env->alloc->next_id; if(!w->is_bg || w->is_bg_thread) { lock_basic_lock(&ctx->cfglock); } - if(!(w->env->rnd = ub_initstate(seed, ctx->seed_rnd))) { + if(!(w->env->rnd = ub_initstate(ctx->seed_rnd))) { if(!w->is_bg || w->is_bg_thread) { lock_basic_unlock(&ctx->cfglock); } - seed = 0; libworker_delete(w); return NULL; } @@ -207,7 +202,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) hash_set_raninit((uint32_t)ub_random(w->env->rnd)); } } - seed = 0; if(eb) w->base = comm_base_create_event(eb); diff --git a/respip/respip.c b/respip/respip.c index 2e9313f..7d2a588 100644 --- a/respip/respip.c +++ b/respip/respip.c @@ -475,10 +475,16 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region) if(!ck->rk.dname) return NULL; + if((unsigned)data->count >= 0xffff00U) + return NULL; /* guard against integer overflow in dsize */ dsize = sizeof(struct packed_rrset_data) + data->count * (sizeof(size_t)+sizeof(uint8_t*)+sizeof(time_t)); - for(i=0; icount; i++) + for(i=0; icount; i++) { + if((unsigned)dsize >= 0x0fffffffU || + (unsigned)data->rr_len[i] >= 0x0fffffffU) + return NULL; /* guard against integer overflow */ dsize += data->rr_len[i]; + } d = regional_alloc(region, dsize); if(!d) return NULL; diff --git a/sldns/parse.c b/sldns/parse.c index b62c405..b30264e 100644 --- a/sldns/parse.c +++ b/sldns/parse.c @@ -325,8 +325,14 @@ sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim, if (c == '\n' && p != 0) { /* in parentheses */ /* do not write ' ' if we want to skip spaces */ - if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) + if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) { + /* check for space for the space character */ + if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { + *t = '\0'; + return -1; + } *t++ = ' '; + } lc = c; continue; } diff --git a/sldns/str2wire.c b/sldns/str2wire.c index 1a51bb6..414b7b8 100644 --- a/sldns/str2wire.c +++ b/sldns/str2wire.c @@ -150,6 +150,10 @@ int sldns_str2wire_dname_buf_origin(const char* str, uint8_t* buf, size_t* len, if(s) return s; if(rel && origin && dlen > 0) { + if((unsigned)dlen >= 0x00ffffffU || + (unsigned)origin_len >= 0x00ffffffU) + /* guard against integer overflow in addition */ + return RET_ERR(LDNS_WIREPARSE_ERR_GENERAL, *len); if(dlen + origin_len - 1 > LDNS_MAX_DOMAINLEN) return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, LDNS_MAX_DOMAINLEN); @@ -168,7 +172,9 @@ uint8_t* sldns_str2wire_dname(const char* str, size_t* len) uint8_t dname[LDNS_MAX_DOMAINLEN+1]; *len = sizeof(dname); if(sldns_str2wire_dname_buf(str, dname, len) == 0) { - uint8_t* r = (uint8_t*)malloc(*len); + uint8_t* r; + if(*len > sizeof(dname)) return NULL; + r = (uint8_t*)malloc(*len); if(r) return memcpy(r, dname, *len); } *len = 0; @@ -187,6 +193,9 @@ rrinternal_get_owner(sldns_buffer* strbuf, uint8_t* rr, size_t* len, sldns_buffer_position(strbuf)); } + if(token_len < 2) /* make sure there is space to read "@" or "" */ + return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, + sldns_buffer_position(strbuf)); if(strcmp(token, "@") == 0) { uint8_t* tocopy; if (origin) { @@ -1094,7 +1103,7 @@ int sldns_str2wire_str_buf(const char* str, uint8_t* rd, size_t* len) while(sldns_parse_char(&ch, &s)) { if(sl >= 255) return RET_ERR(LDNS_WIREPARSE_ERR_INVALID_STR, s-str); - if(*len < sl+1) + if(*len < sl+2) return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, s-str); rd[++sl] = ch; @@ -2095,6 +2104,8 @@ int sldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len) char* s; int n; n = strtol(str, &s, 10); + if(n < 0) /* negative number not allowed */ + return LDNS_WIREPARSE_ERR_SYNTAX; if(*len < ((size_t)n)+2) return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; if(n > 65535) diff --git a/sldns/wire2str.c b/sldns/wire2str.c index 832239f..a95c9b3 100644 --- a/sldns/wire2str.c +++ b/sldns/wire2str.c @@ -585,6 +585,7 @@ static int rr_comment_dnskey(char** s, size_t* slen, uint8_t* rr, if(rrlen < dname_off + 10) return 0; rdlen = sldns_read_uint16(rr+dname_off+8); if(rrlen < dname_off + 10 + rdlen) return 0; + if(rdlen < 2) return 0; rdata = rr + dname_off + 10; flags = (int)sldns_read_uint16(rdata); w += sldns_str_print(s, slen, " ;{"); @@ -781,7 +782,7 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, /* spool labels onto the string, use compression if its there */ uint8_t* pos = *d; unsigned i, counter=0; - const unsigned maxcompr = 1000; /* loop detection, max compr ptrs */ + const unsigned maxcompr = 256; /* loop detection, max compr ptrs */ int in_buf = 1; if(*dlen == 0) return sldns_str_print(s, slen, "ErrorMissingDname"); if(*pos == 0) { @@ -789,7 +790,7 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, (*dlen)--; return sldns_str_print(s, slen, "."); } - while(*pos) { + while((!pkt || pos < pkt+pktlen) && *pos) { /* read label length */ uint8_t labellen = *pos++; if(in_buf) { (*d)++; (*dlen)--; } diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index d165417..2884309 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -407,19 +407,19 @@ static void print_stats_shm(const char* cfgfile) if(!config_read(cfg, cfgfile, NULL)) fatal_exit("could not read config file"); /* get shm segments */ - id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R|SHM_W); + id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R); if(id_ctl == -1) { fatal_exit("shmget(%d): %s", cfg->shm_key, strerror(errno)); } - id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R|SHM_W); + id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R); if(id_arr == -1) { fatal_exit("shmget(%d): %s", cfg->shm_key+1, strerror(errno)); } - shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, 0); + shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, SHM_RDONLY); if(shm_stat == (void*)-1) { fatal_exit("shmat(%d): %s", id_ctl, strerror(errno)); } - stats = (struct ub_stats_info*)shmat(id_arr, NULL, 0); + stats = (struct ub_stats_info*)shmat(id_arr, NULL, SHM_RDONLY); if(stats == (void*)-1) { fatal_exit("shmat(%d): %s", id_arr, strerror(errno)); } diff --git a/testcode/unitmain.c b/testcode/unitmain.c index fecde80..96a6654 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -537,10 +537,8 @@ rnd_test(void) struct ub_randstate* r; int num = 1000, i; long int a[1000]; - unsigned int seed = (unsigned)time(NULL); unit_show_feature("ub_random"); - printf("ub_random seed is %u\n", seed); - unit_assert( (r = ub_initstate(seed, NULL)) ); + unit_assert( (r = ub_initstate(NULL)) ); for(i=0; i= 0); diff --git a/util/data/dname.c b/util/data/dname.c index b744f06..923be02 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -75,6 +75,8 @@ dname_valid(uint8_t* dname, size_t maxlen) { size_t len = 0; size_t labellen; + if(maxlen == 0) + return 0; /* too short, shortest is '0' root label */ labellen = *dname++; while(labellen) { if(labellen&0xc0) @@ -345,11 +347,17 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_type h) void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) { /* copy over the dname and decompress it at the same time */ + size_t comprcount = 0; size_t len = 0; uint8_t lablen; lablen = *dname++; while(lablen) { if(LABEL_IS_PTR(lablen)) { + if(comprcount++ > MAX_COMPRESS_PTRS) { + /* too many compression pointers */ + *to = 0; /* end the result prematurely */ + return; + } /* follow pointer */ if((size_t)PTR_OFFSET(lablen, *dname) >= sldns_buffer_limit(pkt)) @@ -358,6 +366,10 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) lablen = *dname++; continue; } + if(lablen > LDNS_MAX_LABELLEN) { + *to = 0; /* end the result prematurely */ + return; + } log_assert(lablen <= LDNS_MAX_LABELLEN); len += (size_t)lablen+1; if(len >= LDNS_MAX_DOMAINLEN) { diff --git a/util/data/msgreply.c b/util/data/msgreply.c index df2131c..dbae34d 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -238,10 +238,10 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, break; } if(len) { + log_assert(len <= pkt_len); memmove(to, sldns_buffer_current(pkt), len); to += len; sldns_buffer_skip(pkt, (ssize_t)len); - log_assert(len <= pkt_len); pkt_len -= len; } rdf++; diff --git a/util/random.c b/util/random.c index 8332960..9380502 100644 --- a/util/random.c +++ b/util/random.c @@ -86,8 +86,7 @@ ub_systemseed(unsigned int ATTR_UNUSED(seed)) } struct ub_randstate* -ub_initstate(unsigned int ATTR_UNUSED(seed), - struct ub_randstate* ATTR_UNUSED(from)) +ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) { struct ub_randstate* s = (struct ub_randstate*)malloc(1); if(!s) { @@ -123,8 +122,8 @@ void ub_systemseed(unsigned int ATTR_UNUSED(seed)) { } -struct ub_randstate* ub_initstate(unsigned int ATTR_UNUSED(seed), - struct ub_randstate* ATTR_UNUSED(from)) +struct ub_randstate* +ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) { struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); if(!s) { @@ -140,7 +139,9 @@ long int ub_random(struct ub_randstate* ATTR_UNUSED(state)) /* random 31 bit value. */ SECStatus s = PK11_GenerateRandom((unsigned char*)&x, (int)sizeof(x)); if(s != SECSuccess) { - log_err("PK11_GenerateRandom error: %s", + /* unbound needs secure randomness for randomized + * ID bits and port numbers in packets to upstream servers */ + fatal_exit("PK11_GenerateRandom error: %s", PORT_ErrorToString(PORT_GetError())); } return x & MAX_VALUE; @@ -166,8 +167,7 @@ void ub_systemseed(unsigned int ATTR_UNUSED(seed)) log_err("Re-seeding not supported, generator untouched"); } -struct ub_randstate* ub_initstate(unsigned int seed, - struct ub_randstate* ATTR_UNUSED(from)) +struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) { struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); uint8_t buf[YARROW256_SEED_FILE_SIZE]; @@ -183,15 +183,10 @@ struct ub_randstate* ub_initstate(unsigned int seed, yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf); s->seeded = yarrow256_is_seeded(&s->ctx); } else { - /* Stretch the uint32 input seed and feed it to Yarrow */ - uint32_t v = seed; - size_t i; - for(i=0; i < (YARROW256_SEED_FILE_SIZE/sizeof(seed)); i++) { - memmove(buf+i*sizeof(seed), &v, sizeof(seed)); - v = v*seed + (uint32_t)i; - } - yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf); - s->seeded = yarrow256_is_seeded(&s->ctx); + log_err("nettle random(yarrow) cannot initialize, " + "getentropy failed: %s", strerror(errno)); + free(s); + return NULL; } return s; diff --git a/util/random.h b/util/random.h index a05a994..e75157d 100644 --- a/util/random.h +++ b/util/random.h @@ -57,15 +57,12 @@ void ub_systemseed(unsigned int seed); /** * Initialize a random generator state for use - * @param seed: seed value to create state contents. - * (ignored for arc4random). * @param from: if not NULL, the seed is taken from this random structure. * can be used to seed random states via a parent-random-state that * is itself seeded with entropy. * @return new state or NULL alloc failure. */ -struct ub_randstate* ub_initstate(unsigned int seed, - struct ub_randstate* from); +struct ub_randstate* ub_initstate(struct ub_randstate* from); /** * Generate next random number from the state passed along. diff --git a/util/regional.c b/util/regional.c index 899a54e..5be09eb 100644 --- a/util/regional.c +++ b/util/regional.c @@ -120,8 +120,18 @@ regional_destroy(struct regional *r) void * regional_alloc(struct regional *r, size_t size) { - size_t a = ALIGN_UP(size, ALIGNMENT); + size_t a; void *s; + if( +#if SIZEOF_SIZE_T == 8 + (unsigned long long)size >= 0xffffffffffffff00ULL +#else + (unsigned)size >= (unsigned)0xffffff00UL +#endif + ) + return NULL; /* protect against integer overflow in + malloc and ALIGN_UP */ + a = ALIGN_UP(size, ALIGNMENT); /* large objects */ if(a > REGIONAL_LARGE_OBJECT_SIZE) { s = malloc(ALIGNMENT + size); diff --git a/util/shm_side/shm_main.c b/util/shm_side/shm_main.c index a783c09..69bee4d 100644 --- a/util/shm_side/shm_main.c +++ b/util/shm_side/shm_main.c @@ -121,7 +121,7 @@ int shm_main_init(struct daemon* daemon) shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL); /* SHM: Create the segment */ - daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0666); + daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0644); if (daemon->shm_info->id_ctl < 0) { @@ -134,7 +134,7 @@ int shm_main_init(struct daemon* daemon) return 0; } - daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0666); + daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0644); if (daemon->shm_info->id_arr < 0) { diff --git a/validator/autotrust.c b/validator/autotrust.c index 7bc5577..e19bd7b 100644 --- a/validator/autotrust.c +++ b/validator/autotrust.c @@ -370,10 +370,10 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, free(tp); return NULL; } - lock_basic_unlock(&anchors->lock); lock_basic_init(&tp->lock); lock_protect(&tp->lock, tp, sizeof(*tp)); lock_protect(&tp->lock, tp->autr, sizeof(*tp->autr)); + lock_basic_unlock(&anchors->lock); return tp; }