Fix CVE-2020-12662 and CVE-2020-12663

This commit is contained in:
W.C.A. Wijngaards
2020-05-19 08:17:45 +02:00
parent 114764658d
commit 50d4c893c4
9 changed files with 246 additions and 72 deletions
+30
View File
@@ -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;
+5 -1
View File
@@ -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. */