Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This pull request makes the following additions & changes:
TestDecodeDnsAnswer_PathologicalPacket
) that demonstrates how the current non-strict version ofParseLabels
can be (ab)used with a ~65 kilobyte packet that takes lots of CPU power and multiple gigabytes of memory to parse.ParseLabels
quite a bit stricter about the input it accepts:The comments in the pathological packet code try to explain the logic behind it, but in short the idea is to create a message with one question and N CNAME answers. The question contains a very long (too long) name composed of chunks of oversized labels that are interleaved to save space. Each chunk is then followed by a burst of pointers that try to duplicate the data as much as possible, the last pointer jumping forwards and continuing decoding. The name is neatly finished with a null byte when we can't fit any more data to the first 16383 bytes that pointers can point to. A quick check seems to indicate that a name that's encoded like this takes somewhere around 700 kilobytes of memory (don't quote me on this).
The question is then followed by as many CNAME answers as we can fit into the remaining message space. Each answer is kept as short as possible and points just to the name in the question, so that the already bloated name gets copied many times in the memory.
In my Docker-based dev environment the test takes multiple gigabytes of memory and times out after 240 seconds or so.
I made the pathological case the first commit in this pull request so that it can be easily tested against the non-strict version of
ParseLabels
:git checkout 3811d0e088002883551786e270c4af7f4a2a0cee go test ./dnsutils -v -run PathologicalPacket