fix multiple validation issues in dns response label parsing
Due to an error introduced in commit fcc522c923,
checking of the remaining output buffer space was not performed correctly,
allowing malformed input to write past the end of the buffer.
In addition, the loop detection logic failed to account for the possibility
of infinite loops with no output, which would hang the function.
The output size is now limited more strictly so only names with valid length
are accepted.
This commit is contained in:
parent
7e222f46a8
commit
b3d9e0b94e
1 changed files with 6 additions and 4 deletions
|
|
@ -4,10 +4,11 @@
|
|||
int __dn_expand(const unsigned char *base, const unsigned char *end, const unsigned char *src, char *dest, int space)
|
||||
{
|
||||
const unsigned char *p = src;
|
||||
int len = -1, j;
|
||||
if (space > 256) space = 256;
|
||||
char *dend = dest + (space > 254 ? 254 : space);
|
||||
int len = -1, i, j;
|
||||
if (p==end || !*p) return -1;
|
||||
for (;;) {
|
||||
/* detect reference loop using an iteration counter */
|
||||
for (i=0; i < end-base; i+=2) {
|
||||
if (*p & 0xc0) {
|
||||
if (p+1==end) return -1;
|
||||
j = ((p[0] & 0x3f) << 8) | p[1];
|
||||
|
|
@ -16,7 +17,7 @@ int __dn_expand(const unsigned char *base, const unsigned char *end, const unsig
|
|||
p = base+j;
|
||||
} else if (*p) {
|
||||
j = *p+1;
|
||||
if (j>=end-p || j>space) return -1;
|
||||
if (j>=end-p || j>dend-dest) return -1;
|
||||
while (--j) *dest++ = *++p;
|
||||
*dest++ = *++p ? '.' : 0;
|
||||
} else {
|
||||
|
|
@ -24,6 +25,7 @@ int __dn_expand(const unsigned char *base, const unsigned char *end, const unsig
|
|||
return len;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
weak_alias(__dn_expand, dn_expand);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue