mirror of
https://github.com/3proxy/3proxy.git
synced 2026-11-05 01:15:48 +08:00
resolve: the PTR answer of dnsname walked inside its record data
The label walk of a DNS PTR answer ran to the end of the whole message, not to the end of the record's data, and took a compression pointer for a label length, so it could write past the end of the answer buffer on the stack. An answer of 3841 bytes or more reached past the buffer itself. A record that ended exactly at the end of the message was also read one byte past it. The walk now stops at the end of the record's data, a name that does not end there, or one that is compressed or empty is not accepted, and the answer loop reads nothing past the message.
This commit is contained in:
parent
9be415b731
commit
e9714fa4df
@ -167,6 +167,7 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
||||
k += 4;
|
||||
if(na > 255) na = 255; /* somebody is very evil */
|
||||
for (j = 0; j < na; j++) { /* now there should be answers */
|
||||
if(k >= len) break;
|
||||
while(buf[k] < 192 && buf[k] !=0 && (k+buf[k]+14) < len) k+= (buf[k] + 1);
|
||||
if(!buf[k]) k--;
|
||||
if((k+(af == AF_INET6?28:16)) > len) {
|
||||
@ -195,15 +196,17 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
||||
k+= (12 + flen);
|
||||
continue; /* we need A PTR */
|
||||
}
|
||||
for (s2 = buf + k + 12; s2 < (buf + k + 12 + len) && *s2; ){
|
||||
s1 = s2 + ((unsigned)*s2) + 1;
|
||||
s1 = buf + k + 12 + flen; /* the end of this record's data, inside the answer */
|
||||
for (s2 = buf + k + 12; s2 < s1 && *s2 && *s2 < 64; ){
|
||||
unsigned char *next = s2 + ((unsigned)*s2) + 1;
|
||||
*s2 = '.';
|
||||
s2 = s1;
|
||||
s2 = next;
|
||||
}
|
||||
*s2 = 0;
|
||||
if(s2 >= s1 || *s2 || s2 == buf + k + 12)
|
||||
break; /* the name runs past its data, is compressed or empty */
|
||||
if(param->username)free(param->username);
|
||||
param->username = (unsigned char *)strdup ((char *)buf + k + 13);
|
||||
|
||||
|
||||
return udpresolve(af,param->username, value, NULL, NULL, 2);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user