-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix crashing induced by Zonemaster::LDNS::RR::NSEC3::salt() method #177
Fix crashing induced by Zonemaster::LDNS::RR::NSEC3::salt() method #177
Conversation
The salt() method in the Zonemaster::LDNS::RR::NSEC3 module never worked and often caused the Perl interpreter to crash. This commit fixes many long-standing issues with the affected code. Firstly, the root cause of the crash is a double free resulting from the inappropriate use of ldns_rdf_deep_free() in the code. The ldns_nsec3_salt() function returns a pointer to a ldns_rdf structure which is just a window into the salt field, not a copy of the data. So calling ldns_rdf_deep_free() on that ldns_rdf object causes a part of the original resource record structure to be freed instead. This then results in a double free when the memory for the resource record object is deallocated. Calling ldns_rdf_free() instead fixes the crashing. Secondly, the method doesn’t quite return the salt: it actually returns a string containing the salt preceded by its length byte. This is surprising, not as documented and unlikely to be useful. This problem is fixed by rewriting the entire function so as to return the salt, all the salt and nothing but the salt. Thirdly, the method was also insufficiently covered by unit tests. Tests were added, first to help reproduce the crashes, but also to cover the case of an NSEC3 with non-empty salt. Finally, the method returns undef if the salt is empty. Not only is that documented nowhere, but the choice of doing so is questionable. This commit changes the behavior somewhat in this case: if the salt is empty, an empty string is returned instead; the method only returns undef if there was a problem accessing the salt field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine. Are there calls in Engine that have to be updated to match this change?
I did a |
Purpose
The
salt()
method in theZonemaster::LDNS::RR::NSEC3
module never worked and often caused the Perl interpreter to crash. This PR fixes many long-standing issues with the affected code.Firstly, the root cause of the crash is a double free resulting from the inappropriate use of
ldns_rdf_deep_free()
in the code. Theldns_nsec3_salt()
function returns a pointer to aldns_rdf
structure which is just a window into the salt field, not a copy of the data. So callingldns_rdf_deep_free()
on thatldns_rdf
object causes a part of the original resource record structure to be freed instead. This then results in a double free when the memory for the resource record object is deallocated. Removing the call to that function fixes the crashing.Secondly, the method doesn’t quite return the salt: it actually returns a string containing the salt preceded by its length byte. This is surprising, not as documented and unlikely to be useful. This problem is fixed by rewriting the entire function so as to return the salt, all the salt and nothing but the salt.
Thirdly, the method was also insufficiently covered by unit tests. Tests were added, first to help reproduce the crashes, but also to cover the case of an NSEC3 with non-empty salt.
Finally, the method returns
undef
if the salt is empty. Not only is that documented nowhere, but the choice of doing so is questionable. This PR changes the behavior somewhat in this case: if the salt is empty, an empty string is returned instead; the method only returnsundef
if there was a problem accessing the salt field.Context
Found by @tgreenx while updating the implementation of DNSSEC03 (see PR zonemaster/zonemaster-engine#1304).
Changes
salt()
method in Zonemaster::LDNS::RR::NSEC3 completelyNote: because the function’s behavior is changed in the case of a resource record with an empty salt, this change should be considered breaking.
How to test this PR
Unit tests should pass.