diff --git a/dnscrypt/dnscrypt.c b/dnscrypt/dnscrypt.c index 2b38a1cdb..72a9527f5 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 9803ae8cc..7398075e1 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -9,6 +9,8 @@ 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. 18 November 2019: Wouter - In unbound-host use separate variable for get_option to please diff --git a/respip/respip.c b/respip/respip.c index 36a1c9726..482762b50 100644 --- a/respip/respip.c +++ b/respip/respip.c @@ -479,10 +479,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;