musl bounds DNS results independently of the requested record type
A DNS response can contain more small address records than musl's precomputed bound expected. The fix checks the accumulated result count before the parsing callback writes another address.
A bound derived from the question sent over a network is unsafe if the answer can violate the assumption behind that calculation. The October 19 musl disclosure describes that problem in DNS response parsing. When a program requests both IPv4 and IPv6 results, the resolver sends A and AAAA queries. A malicious or spoofed nameserver can answer both with A records, which are smaller and can produce more addresses than the implementation expected.
Rich Felker credits Felix Wilhelm with discovering the flaw and identifies musl 1.1.16 and earlier as affected. The result is an overflow of a stack-based buffer. The October 18 correction adds a direct check of the accumulated address count in the DNS parsing callback. This small patch changes where the implementation establishes its safety property.
I regard the distinction between a calculated expectation and an enforced limit as central to writing C well. A fixed-capacity array can be adequate for every expected reply and still be unsafe when its writer accepts a different reply. The capacity needs to constrain the operation that consumes the untrusted data.
Two replies share an output capacity
The disclosure identifies getaddrinfo with AF_UNSPEC as the relevant application request. The resolver asks for both address families. Those queries differ in their expected resource-record types, but their results contribute addresses to a common output collection.
The patch explanation says that MAXADDRS was originally chosen so that enforcement appeared unnecessary. Its calculation assumed that only one reply would contain A answers. The corresponding assumption for the other reply was the larger AAAA representation, which permits fewer address records in a bounded message.
That reasoning used a property of the anticipated contents, not just the maximum byte length of the messages. If both answer sections contain A records, the number of represented addresses can exceed the calculated bound while each response still fits the input space available for it. Bounding the input messages therefore does not establish the output collection's capacity requirement.
This is a transformation problem. The parser receives bytes, recognizes records and emits address objects. Its input-byte limit and output-element limit have different units. A proof that connects them must cover the actual accepted record types, including combinations the requester did not intend to receive.
The failure does not require an application to ask for an unusually large result array. It occurs within the library's implementation of an ordinary dual-family request. The attacker influences response contents, while the resolver's internal callback determines how many address objects those contents cause it to write.
The callback now checks its own count
The patch inserts a check immediately after recovering the parser context. It precedes the switch on the record type, so a full output collection prevents further callback processing through that path.
if (ctx->cnt >= MAXADDRS) return -1;
This is an excerpt from the implementation correction, not an application API. ctx->cnt tracks the number of addresses already collected, and MAXADDRS is the output capacity. Testing before another address write prevents the accepted record mix from bypassing the bound.
The inequality includes equality because a count equal to the capacity means every valid output slot is already occupied. A further insertion would use an index outside the collection. Keeping the test beside parsing also reduces dependence on a separate argument that every possible response combination must fit.
The patch does not need to infer the attacker's intention. It can enforce the same rule for malformed replies and unexpected but parseable record mixtures. The property needed at that point is simply that the next operation must not add an address beyond the available capacity.
It is useful that the patch explanation records why the original reasoning failed. Describing the issue only as a missing bounds check would omit the mistaken premise that made the omission seem safe. The implementation expected an upper bound from protocol behavior that the received data did not have to respect.
Nameserver trust determines the attack condition
Felker describes an attacker who controls, or can spoof, the nameservers configured in resolv.conf. That is a concrete condition on the resolver's input. The disclosure does not say that every arbitrary remote host can exploit every program that links musl, and the scope should remain tied to the ability to supply those responses.
The recommendation is to upgrade to 1.1.17 or apply the patch. The message says the patch is simple and should apply cleanly to recent versions. This makes the source correction relevant to users who cannot immediately replace the whole libc installation, while the release recommendation provides a versioned route for users who can.
For users unable to patch or upgrade immediately, the disclosure proposes a caching nameserver on localhost and pointing resolv.conf at 127.0.0.1. That is the mitigation stated by the maintainer. It should remain distinguishable from the source fix, which directly enforces the destination bound regardless of the assumption about reply types.
The public message is a CVE request. It supplies the affected versions, the triggering query combination and a patch link, but does not provide a numbered CVE identifier in its text. There is no need to add an identifier from a later record to explain the flaw as disclosed today.
Capacity must describe accepted input
I prefer the explicit callback check because it gives the writer of each address a local condition to preserve. The resolver can still calculate capacities and use protocol knowledge, but the final insertion no longer depends entirely on the reply matching the original query's expected type. That makes the relevant safety condition visible at the point where the parser converts received records into stored addresses.
The broader lesson here is specific to that conversion. A bounded DNS message can hold different numbers of records depending on their representation, and two bounded messages can contribute to the same output. The October correction caps that combined count directly. It closes the gap between the number of addresses the implementation predicted and the number the accepted responses could actually supply.