Skip to content

fix(netdb): Buffer overrun when parsing DNS

Josh Megnauth requested to merge josh/relibc:fix-dns-extra-output into master

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

Merge request reports