rr: limit the amount of allowed rr descriptors#294
rr: limit the amount of allowed rr descriptors#294xypiie wants to merge 1 commit intoNLnetLabs:developfrom
Conversation
A malicious DNS server could send an answer causing ldns to assume millions of rr descriptors. This could cause ldns consuming hundrets of MiB's of memory which then could cause the OOM handler to step in and kill the process. Thus we want to limit the amount of allowed descriptors to prevent this from being used as remote DoS attacks. Issue found by Maciej Musial, Robert Rozanski and Monika Walendzik. Signed-off-by: Peter Kästle <peter.kaestle@nokia.com>
|
I uploaded patches to reproduce the issue here: |
|
Thanks. ldns_rr_desciptor_maximum returns the maximum number of rdata fields (see: https://nlnetlabs.nl/documentation/ldns/rr_8h.html#a903dbeb5f9d525abf9d9503102dc3cc8 ). Realistically, this can be maximally 65535 as limited by rdlength. (so not millions) Your example in On my system, your debugging program reports +- 209MiB memory usage for the raw_answer_producing_huge_memload packet. This is indeed rather large. If memory was optimally utilized, this should in theory (with how ldns handles data) on a 64 bit system just take 32 * 16384 = 0.5MiB (so 400 times less). I think some optimizations could be made (for example trying to limit the number of needed reallocations, or using a region allocator like unbound and/or nsd do), but this is all quite involved. The example packet does contain a valid DNS RR, and I think ldns should be able to handle it. If low memory usage is vital to you, you may have a look at sldns, which is a version of ldns (part of unbound) that doesn't take apart wireformat packets into malloced pieces in host format, but reads and writes wire and presentation format directly: https://github.com/NLnetLabs/unbound/tree/master/sldns I'm willing to limit the number of rdata fields enabled and set with an option to configure, but packets crafted in other ways, for example to maximize the number of RRs in a RRset would have similar results (though less bad, since they have more content for each malloc). |
|
I meant that it's millions, because of the The following printf makes it visible on top of https://github.com/xypiie/ldns/tree/huge_mem_reproducer: output: Low memory usage is not the ultimate goal I'm looking for. Security is. Thus the point I wanted to make is, that a crafted response from a remote dns server will cause the memory usage to grow massively beyond the "normal" ~8MiB of e.g. drill. And this will be the case for all users of ldns library, when they get such an crafted response. Yes, some optimization on the memory handling would be great. What would be your proposal to "limit the number of rdata fields enabled and set with an option to configure"? |
Yes, that return is misleading as there is another restriction (rdlength) which would limit this. If we assume a minimum rdata field size of 1, anything larger than 65535 doesn't make sense anyway. I'll adapt that number to 65535. |
I'm proposing an option to configure to limit the maximum: |
Done now in commit b7a7918 . I also took the opportunity to provide better names for the functions (ldns_minimum_rdata_fields and ldns_maximum_rdata_fields) |
Ok, thanks a lot, please ping once you have the commit for this configure option and I'll retest and close this PR then. |
A malicious DNS server could send an answer causing ldns to assume millions of rr descriptors.
This could cause ldns consuming hundrets of MiB's of memory which then could cause the OOM handler to step in and kill the process.
Thus we want to limit the amount of allowed descriptors to prevent this from being used as remote DoS attacks.
Issue found by Maciej Musial, Robert Rozanski and Monika Walendzik.