Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240818020328.GU10433@brightrain.aerifal.cx>
Date: Sat, 17 Aug 2024 22:03:28 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Adding dns/resolver tests to libc-test

I've been working on a framework to allow testing of libc resolver/dns
functionality in libc-test, on Linux-based hosts, provided they have
user-namespace functionality. The intent is that these tests would be
made conditional on __linux__ or similar, with the freedom to add
equivalent setup for other systems in the future if desired.

I'm attaching a semi-polished (fallback and error handling should be
mostly right) helper module that sets up the namespaced environment
for the test in-process. The intended usage pattern would be putting a
number of resolver tests in a single file, which would first call the
enter_dns_test_ns() setup function, then sequentially run each test.
For tests looking for crashes from malformed responses, it would make
sense to fork a child for the test to run in, and wait in the parent.

Each test would:

1. Truncate and rewrite /etc/resolv.conf and /etc/hosts (these are
   virtual replacements which only appear in the namespace) with
   desired contents. This would involve putting "nameserver 127.0.0.1"
   (or ::1 to test IPv6 nameserver support) in resolv.conf, and may
   also need options to disable functionality like edns0 that might
   not match the test payload.

2. Create a thread to listen on localhost:53 and respond with the
   packet contents to test the resolver against. Normally these would
   be hard-coded packets except for rewriting the query id to match
   (or mismatch, if testing rejection of mismatched id) the query, and
   selecting a reply based on the requested RR type. Should listen on
   both UDP and TCP unless testing the behavior when one or the other
   is not available.

3. From the main thread, call getaddrinfo, getnameinfo, get*by*[_r],
   res_query, res_send, etc. as desired to test against the payload.

4. Evaluate that the results match the expectation.

A smart direction to go from here, I think, would be looking back over
DNS-related bugs and limitations (like CNAME chain length) we've had
in the past and collecting or constructing test payloads to trigger
them.

It should be possible to capture responses from the real world with a
simple program using res_query, and incorporate them into tests. If
doing so, my leaning would be to anonymize the actual contents
(replace domains with example.com, IPs with private-use ranges), but
maybe that doesn't matter? Using the arpa/nameser.h interfaces in libc
it's probably easy enough to find all the data one may want to replace
in a packet and replace it.

Anyone up for fleshing some of this out?

Rich

View attachment "unshare-ns.c" of type "text/plain" (3137 bytes)

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.