| Fixes heap buffer overflow in ares_mkquery. |
| |
| If name ends with "\.", ares_mkquery allocates a query buffer that is |
| one byte too small. |
| |
| https://crbug.com/649040 |
| |
| --- c-ares-1.7.5/ares_mkquery.c |
| +++ c-ares-1.7.5/ares_mkquery.c |
| @@ -96,20 +96,22 @@ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, |
| *buflen = 0; |
| *buf = NULL; |
| |
| - /* Compute the length of the encoded name so we can check buflen. |
| - * Start counting at 1 for the zero-length label at the end. */ |
| + /* Compute the length of the encoded name so we can allocate the buffer. |
| + * Start counting at 1 to account for the first label's length field. */ |
| len = 1; |
| for (p = name; *p; p++) |
| { |
| + /* The length field of the last label is accounted for below. */ |
| + if (*p == '.' && *(p + 1) == 0) |
| + break; |
| if (*p == '\\' && *(p + 1) != 0) |
| p++; |
| len++; |
| } |
| - /* If there are n periods in the name, there are n + 1 labels, and |
| - * thus n + 1 length fields, unless the name is empty or ends with a |
| - * period. So add 1 unless name is empty or ends with a period. |
| - */ |
| - if (*name && *(p - 1) != '.') |
| + |
| + /* Account for the length field of the last label. If the name is "." or |
| + * empty, the last label is the first label, which was already counted. */ |
| + if (*name && strcmp(name, ".") != 0) |
| len++; |
| |
| /* Immediately reject names that are longer than the maximum of 255 |