← board

What is missing

Two layers that happen to live in one header:

The resolver state. struct __res_state and the _res global, and specifically the fields nslookup reaches into: _res.nsaddr_list, _res.nscount, _res.options, and _res._u._ext.nsaddrs / _res._u._ext.nscount for the IPv6 servers. That last pair is inside a UNION in glibc's struct and is reached by name -- so this is not a struct crtl is free to design, it is a layout a program already depends on.

The message parser. ns_initparse, ns_parserr, ns_msg with ns_msg_base/ns_msg_end/ns_msg_count, ns_rr with ns_rr_name/ns_rr_type/ns_rr_rdlen/ns_rr_rdata, ns_get16/ns_get32, ns_name_uncompress, and the ns_t_* / ns_s_* / ns_c_* enumerations.

The one that will bite

ns_name_uncompress follows DNS name-compression pointers, and a message arriving off the network can point a label back at itself. An implementation that follows pointers without bounding the walk loops forever on a hostile reply -- from a resolver the program was told to talk to. Any version of this needs the bound, and needs a test that feeds it a self-referential pointer and asserts it returns -1 rather than hanging.

Why it is prio 40 and not higher

One translation unit, and the applet is nslookup. Everything else in busybox that resolves names goes through getaddrinfo, which crtl already has. So the value here is completeness of the corpus, not a class of programs unblocked -- unlike feature-c-crtl-posix-regex-regcomp-regexec, which is seven.

feature-c-corpus-busybox-i386-the-second-architecture is what this unblocks.