mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-09-12 04:47:41 +02:00
Fix CVE-2020-12662 and CVE-2020-12663
This commit is contained in:
@@ -233,17 +233,28 @@ int
|
||||
dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
|
||||
{
|
||||
uint8_t len1, len2;
|
||||
int count1 = 0, count2 = 0;
|
||||
log_assert(pkt && d1 && d2);
|
||||
len1 = *d1++;
|
||||
len2 = *d2++;
|
||||
while( len1 != 0 || len2 != 0 ) {
|
||||
/* resolve ptrs */
|
||||
if(LABEL_IS_PTR(len1)) {
|
||||
if((size_t)PTR_OFFSET(len1, *d1)
|
||||
>= sldns_buffer_limit(pkt))
|
||||
return -1;
|
||||
if(count1++ > MAX_COMPRESS_PTRS)
|
||||
return -1;
|
||||
d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1));
|
||||
len1 = *d1++;
|
||||
continue;
|
||||
}
|
||||
if(LABEL_IS_PTR(len2)) {
|
||||
if((size_t)PTR_OFFSET(len2, *d2)
|
||||
>= sldns_buffer_limit(pkt))
|
||||
return 1;
|
||||
if(count2++ > MAX_COMPRESS_PTRS)
|
||||
return 1;
|
||||
d2 = sldns_buffer_at(pkt, PTR_OFFSET(len2, *d2));
|
||||
len2 = *d2++;
|
||||
continue;
|
||||
@@ -302,12 +313,18 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_type h)
|
||||
uint8_t labuf[LDNS_MAX_LABELLEN+1];
|
||||
uint8_t lablen;
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
/* preserve case of query, make hash label by label */
|
||||
lablen = *dname++;
|
||||
while(lablen) {
|
||||
if(LABEL_IS_PTR(lablen)) {
|
||||
/* follow pointer */
|
||||
if((size_t)PTR_OFFSET(lablen, *dname)
|
||||
>= sldns_buffer_limit(pkt))
|
||||
return h;
|
||||
if(count++ > MAX_COMPRESS_PTRS)
|
||||
return h;
|
||||
dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
|
||||
lablen = *dname++;
|
||||
continue;
|
||||
@@ -341,6 +358,9 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname)
|
||||
return;
|
||||
}
|
||||
/* follow pointer */
|
||||
if((size_t)PTR_OFFSET(lablen, *dname)
|
||||
>= sldns_buffer_limit(pkt))
|
||||
return;
|
||||
dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
|
||||
lablen = *dname++;
|
||||
continue;
|
||||
@@ -369,6 +389,7 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname)
|
||||
void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname)
|
||||
{
|
||||
uint8_t lablen;
|
||||
int count = 0;
|
||||
if(!out) out = stdout;
|
||||
if(!dname) return;
|
||||
|
||||
@@ -382,6 +403,15 @@ void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname)
|
||||
fputs("??compressionptr??", out);
|
||||
return;
|
||||
}
|
||||
if((size_t)PTR_OFFSET(lablen, *dname)
|
||||
>= sldns_buffer_limit(pkt)) {
|
||||
fputs("??compressionptr??", out);
|
||||
return;
|
||||
}
|
||||
if(count++ > MAX_COMPRESS_PTRS) {
|
||||
fputs("??compressionptr??", out);
|
||||
return;
|
||||
}
|
||||
dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
|
||||
lablen = *dname++;
|
||||
continue;
|
||||
|
||||
@@ -55,7 +55,11 @@ smart_compare(sldns_buffer* pkt, uint8_t* dnow,
|
||||
{
|
||||
if(LABEL_IS_PTR(*dnow)) {
|
||||
/* ptr points to a previous dname */
|
||||
uint8_t* p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1]));
|
||||
uint8_t* p;
|
||||
if((size_t)PTR_OFFSET(dnow[0], dnow[1])
|
||||
>= sldns_buffer_limit(pkt))
|
||||
return -1;
|
||||
p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1]));
|
||||
if( p == dprfirst || p == dprlast )
|
||||
return 0;
|
||||
/* prev dname is also a ptr, both ptrs are the same. */
|
||||
|
||||
Reference in New Issue
Block a user