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

Segfault when parsing a bad CAA resource record #149

Closed
marc-vanderwal opened this issue Aug 1, 2022 · 3 comments · Fixed by #153
Closed

Segfault when parsing a bad CAA resource record #149

marc-vanderwal opened this issue Aug 1, 2022 · 3 comments · Fixed by #153
Assignees
Labels
T-Bug Type: Bug in software or error in test case description
Milestone

Comments

@marc-vanderwal
Copy link
Contributor

I am using Zonemaster::LDNS version 2.2.2 with libldns-1.7.0 on Ubuntu 20.04 LTS (with WSL).

During fuzz testing, I noticed that Zonemaster::LDNS would sometimes segfault, even when PR #136 is merged (locally). After some searching, I managed to reproduce it consistently when feeding Zonemaster::LDNS with a bad CAA resource record; more specifically, an A record whose type code is changed from 1 to 257 with a random bit flip.

Below is a minimal script that causes the crash:

#!/usr/bin/env perl

use Zonemaster::LDNS;

print "Trying…\n";
my $bad_caa = Zonemaster::LDNS::RR->new('bad-caa.example. 3600 IN CAA \# 4 C0000202');
print "OK\n";

And here is the accompanying GDB output:

$ gdb perl
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from perl...
(No debugging symbols found in perl)
(gdb) run crashme.pl
Starting program: /usr/bin/perl crashme.pl
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Trying…

Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
120     ../sysdeps/x86_64/multiarch/../strlen.S: No such file or directory.
(gdb) bt
#0  __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
#1  0x00007ffff78d06d7 in XS_Zonemaster__LDNS__RR_string (my_perl=<optimized out>, cv=<optimized out>) at src/LDNS.xs:1600
#2  0x000055555565d9d8 in Perl_pp_entersub ()
#3  0x0000555555654136 in Perl_runops_standard ()
#4  0x00005555555d00d7 in Perl_amagic_call ()
#5  0x0000555555671de6 in Perl_sv_2pv_flags ()
#6  0x00007ffff78df7fb in net_ldns_remember (rv=rv@entry=0x5555558af470,
    hashname=hashname@entry=0x7ffff7919db8 "Zonemaster::LDNS::__rrs__") at src/assist.c:78
#7  0x00007ffff78df830 in net_ldns_remember_rr (rv=rv@entry=0x5555558af470) at src/assist.c:51
#8  0x00007ffff78d126d in XS_Zonemaster__LDNS__RR_new_from_string (my_perl=<optimized out>, cv=<optimized out>)
    at src/LDNS.xs:1553
#9  0x000055555565d9d8 in Perl_pp_entersub ()
#10 0x0000555555654136 in Perl_runops_standard ()
#11 0x00005555555c78dc in perl_run ()
#12 0x000055555559d432 in main ()
(gdb) f 1
#1  0x00007ffff78d06d7 in XS_Zonemaster__LDNS__RR_string (my_perl=<optimized out>, cv=<optimized out>) at src/LDNS.xs:1600
1600            RETVAL[strlen(RETVAL)-1] = '\0';
(gdb) p RETVAL
$1 = 0x0
(gdb) q
A debugging session is active.

        Inferior 1 [process 60463] will be killed.

Quit anyway? (y or n) y
@marc-vanderwal
Copy link
Contributor Author

marc-vanderwal commented Aug 31, 2022

Better yet, here’s a one-liner. Expected behavior is no output, instead the following prints Segmentation fault:

perl -MZonemaster::LDNS -e 'Zonemaster::LDNS::RR->new("bad-caa.example. IN CAA \\# 4 C0000202")'

The segfault also happens when using the internal ldns library.

@marc-vanderwal marc-vanderwal self-assigned this Aug 31, 2022
@matsduf matsduf added the T-Bug Type: Bug in software or error in test case description label Aug 31, 2022
@matsduf matsduf added this to the v2022.2 milestone Aug 31, 2022
marc-vanderwal added a commit to marc-vanderwal/zonemaster-ldns that referenced this issue Sep 1, 2022
Add a unit test in packet.t and another one in rr.t to reproduce the
segfaults I observed.

See also issue zonemaster#149.
marc-vanderwal added a commit to marc-vanderwal/zonemaster-ldns that referenced this issue Sep 1, 2022
Add a unit test in packet.t and another one in rr.t to reproduce the
segfaults I observed.

See also issue zonemaster#149.
marc-vanderwal added a commit to marc-vanderwal/zonemaster-ldns that referenced this issue Sep 1, 2022
Add a unit test in packet.t and another one in rr.t to reproduce the
segfaults I observed.

See also issue zonemaster#149.
@marc-vanderwal
Copy link
Contributor Author

Here’s a data file containing (manually) corrupted A records: corrupted-a.txt

This data file is a better test because it gets closer to how I originally discovered the bug.

And when I load it in zonemaster-cli, this happens:

zonemaster-cli --restore corrupted-a.txt --ns ns.test/172.30.131.174
 test
Seconds Level     Message
======= ========= =======
   0.02 ERROR     Nameserver ns.test has an IP address (172.30.131.174) with prefix 172.16/12 referenced in [RFC1918] as a 'Private-Use'.
   0.09 WARNING   Nameserver ns.test has an IP address (172.30.131.174) without PTR configured.
   0.56 NOTICE    There are neither DS nor DNSKEY records for the zone.
   0.56 NOTICE    The zone is not signed with DNSSEC.
   0.56 ERROR     Parent does not list enough (1) nameservers (ns.test). Lower limit set to 2.
   0.56 ERROR     Child does not list enough (1) nameservers (ns.test). Lower limit set to 2.
   0.56 ERROR     Child does not list enough (1) nameservers (ns.test) that resolve to IPv4 addresses (172.30.131.174). Lower limit set to 2.
   0.56 NOTICE    Child lists no nameserver that resolves to an IPv6 address. If any were present, the minimum allowed would be 2.
   0.56 ERROR     Delegation does not list enough (1) nameservers (ns.test) that resolve to IPv4 addresses (172.30.131.174). Lower limit set to 2.
   0.56 NOTICE    Delegation lists no nameserver that resolves to an IPv6 address. If any were present, the minimum allowed would be 2.
Segmentation fault

gdb yields a different backtrace:

(gdb) bt
#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65
#1  0x00007ffff7565667 in XS_Zonemaster__LDNS__Packet_string (my_perl=<optimized out>, cv=<optimized out>) at src/LDNS.xs:1236
#2  0x000055555565d2f8 in Perl_pp_entersub ()
#3  0x0000555555653a56 in Perl_runops_standard ()
#4  0x00005555555c77eb in perl_run ()
#5  0x000055555559d432 in main ()
(gdb) f 1
#1  0x00007ffff7565667 in XS_Zonemaster__LDNS__Packet_string (my_perl=<optimized out>, cv=<optimized out>) at src/LDNS.xs:1236
1236            RETVAL[strlen(RETVAL)-1] = '\0';

So there are really two variants of the same issue here. I’m addressing both in a pull request soon to come.

@tgreenx tgreenx linked a pull request Sep 1, 2022 that will close this issue
marc-vanderwal added a commit to marc-vanderwal/zonemaster-ldns that referenced this issue Sep 1, 2022
Add a unit test in packet.t and another one in rr.t to reproduce the
segfaults I observed.

See also issue zonemaster#149.
marc-vanderwal added a commit that referenced this issue Nov 28, 2022
Fix unsafe string manipulations in XS code
@matsduf
Copy link
Contributor

matsduf commented Nov 28, 2022

Resolved by #153

@matsduf matsduf closed this as completed Nov 28, 2022
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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants