fix(netdb): Buffer overrun when parsing DNS
The answers from DNS are NUL terminated. relibc
's parser sometimes replaces the NUL with a '.' and then pops it which often leads to trailing garbage at the end of parsed names.
Run this small program using glibc
/musl
followed by relibc
before and after this patch to test:
#include <assert.h>
#include <netdb.h>
#include <stdint.h>
#include <stdio.h>
#define IP4SIZE (sizeof(uint8_t) * 4)
__attribute__((nonnull))
void host_check(const uint8_t address[4]) {
const struct hostent* host = gethostbyaddr(address, IP4SIZE, AF_INET);
if (!host) {
printf(
"%u.%u.%u.%u => Failed to resolve\n",
address[0],
address[1],
address[2],
address[3]
);
return;
}
printf(
"%u.%u.%u.%u => %s\n",
address[0],
address[1],
address[2],
address[3],
host->h_name
);
}
int main(void) {
const uint8_t addresses[][4] = {
{ 96, 47, 72, 84 },
{ 34, 120, 54, 55 },
{ 23, 21, 162, 66 },
{ 1, 1, 1, 1 },
{ 8, 8, 8, 8 },
{ 8, 8, 4, 4 },
};
const size_t length = sizeof(addresses) / (sizeof(uint8_t) * 4);
for (size_t i = 0; i < length; ++i) {
host_check(addresses[i]);
}
}
Edited by Josh Megnauth