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 unsafe string manipulations in XS code #153

Merged
merged 3 commits into from
Nov 28, 2022

Conversation

marc-vanderwal
Copy link
Contributor

@marc-vanderwal marc-vanderwal commented Sep 1, 2022

Purpose

This PR addresses unsafe string handling in the XS code, called when using the string() method of Zonemaster::LDNS::Packet and Zonemaster::LDNS::RR.

Context

Fixes #149.

Changes

Add checks to the return values of ldns_rr2str() and ldns_pkt2str(). Ensure that the pointers to strings returned by these functions are not NULL and that the strings are not empty before operating on them.

How to test this PR

Unit tests were added which reproduce the circumstances of the crashes I witnessed, so unit tests must pass.

You can also test this PR manually:

  1. Download corrupted-a.txt (attached to Segfault when parsing a bad CAA resource record #149).
  2. Run zonemaster-cli --restore corrupted-a.txt --ns ns.test/172.30.131.174 test and expect no segmentation fault (be sure that it’s using a patched version of Zonemaster::LDNS).
  3. Run the following one-liner:
perl -MZonemaster::LDNS -e 'Zonemaster::LDNS::RR->new("bad-caa.example. IN CAA \\# 4 C0000202")->string'

Expect an error message starting with “Failed to convert RR to string”.

@tgreenx tgreenx added this to the v2022.2 milestone Sep 1, 2022
@tgreenx tgreenx linked an issue Sep 1, 2022 that may be closed by this pull request
@tgreenx tgreenx added the T-Bug Type: Bug in software or error in test case description label Sep 1, 2022
@marc-vanderwal
Copy link
Contributor Author

It seems like attempting to parse the invalid CAA record with Zonemaster::LDNS::RR->new() as I did here isn’t a guaranteed croak. Yet the test that uses Zonemaster::LDNS::RR->new_from_wireformat() does catch an exception. How odd.

I did my testing with the built-in ldns enabled and the new tests pass on my machine (WSL and Ubuntu 20.04). I’ll have to investigate this further.

Add a unit test in packet.t and another one in rr.t to reproduce the
segfaults I observed.

See also issue zonemaster#149.
Fix two instances of unsafe C string manipulations, vulnerable to null
pointer dereferences and out-of-bounds accesses in edge cases.

This was observed as segfaults in zonemaster-cli when attempting to
process the following malformed resource record:

  bad-caa.example.   IN  CAA  \# 4 C0000202

Zonemaster::LDNS::RR and Zonemaster::LDNS::Packet objects can be
converted to a string (i.e. presentation format) with the string()
method. Doing so triggers a call to the ldns_rr2str() and ldns_pkt2str()
C functions respectively.

However, when given some classes of malformed packets, ldns’s functions
fail by returning NULL instead of a valid C string. Normally, these
strings end with a newline, which is removed in the XS code before
returning the result. But the removal of that newline character is
attempted without checking for NULL pointers or empty strings.

With this commit, Zonemaster::LDNS::RR->new() will now croak when given
the aforementioned malformed resource record, and so will
Zonemaster::LDNS::Packet->string() if it contains such a resource
record.
@marc-vanderwal
Copy link
Contributor Author

Oh, I think I know why: my unit test was only a guaranteed croak if the XS code was compiled with -DUSE_ITHREADS. Let’s fix this.

Instantiation of a malformed CAA resource record is a guaranteed croak
if and only if the Perl in use is compiled with support for interpreter
threads (-DUSE_ITHREADS). If not, it won’t. So the unit test is modified
to try to convert the bad CAA record back to presentation form, so that
it does become a guaranteed croak.
Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch and fix!

@matsduf matsduf modified the milestones: v2022.2, v2023.1 Nov 8, 2022
@marc-vanderwal
Copy link
Contributor Author

@matsduf I think it would be a good thing to have this bugfix merged in release v2022.2. What do you think?

@matsduf matsduf modified the milestones: v2023.1, v2022.2 Nov 23, 2022
@matsduf
Copy link
Contributor

matsduf commented Nov 25, 2022

@marc-vanderwal, could this be merged?

@marc-vanderwal marc-vanderwal merged commit 1562cd1 into zonemaster:develop Nov 28, 2022
@hannaeko hannaeko added S-ReleaseTested Status: The PR has been successfully tested in release testing V-Patch Versioning: The change gives an update of patch in version. labels Dec 7, 2022
@marc-vanderwal marc-vanderwal deleted the bugfix/#149 branch August 29, 2024 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-ReleaseTested Status: The PR has been successfully tested in release testing T-Bug Type: Bug in software or error in test case description V-Patch Versioning: The change gives an update of patch in version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Segfault when parsing a bad CAA resource record
4 participants