Skip to content
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

Merged

Conversation

marc-vanderwal
Copy link
Contributor

@marc-vanderwal marc-vanderwal commented Nov 20, 2023

Purpose

The salt() method in the Zonemaster::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. 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. 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 returns undef 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

  • Rewrite the salt() method in Zonemaster::LDNS::RR::NSEC3 completely
  • Add unit tests and update documentation

Note: 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.

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.
@marc-vanderwal marc-vanderwal added T-Bug Type: Bug in software or error in test case description V-Major Versioning: The change gives an update of major in version. labels Nov 20, 2023
@marc-vanderwal marc-vanderwal marked this pull request as ready for review November 20, 2023 10:50
matsduf
matsduf previously approved these changes Nov 20, 2023
Copy link
Contributor

@matsduf matsduf left a 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?

t/rr.t Outdated Show resolved Hide resolved
@marc-vanderwal
Copy link
Contributor Author

This looks fine. Are there calls in Engine that have to be updated to match this change?

I did a git grep on Zonemaster::Engine (with the develop branch checked out) and this method isn’t used anywhere yet.

@marc-vanderwal marc-vanderwal merged commit d079e46 into zonemaster:develop Nov 21, 2023
1 check passed
@marc-vanderwal marc-vanderwal deleted the bugfix/nsec3-salt-method branch August 29, 2024 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-Bug Type: Bug in software or error in test case description V-Major Versioning: The change gives an update of major in version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants