Subject: | Possible use of freed data by Net::DNS::Packet->new(\$data) |
Date: | Wed, 22 Oct 2008 16:53:13 +1100 |
To: | bug-Net-DNS [...] rt.cpan.org |
From: | "Brett Watson" <brett.watson [...] gmail.com> |
This is an issue with Net::DNS 0.63 on Perl 5.8.8 as found in Xubuntu 8.04
(hardy).
In tracking down a difficult-to-diagnose bug, I think I've pinned the blame
on XS code accessed in Net::DNS::Packet->new(). I'm now working around this
bug, so I have no patch to offer, but here are the details of what I found
to aid the maintainers in finding it.
The situation was that I have written two wrapper functions: one for DNS
query via UDP, the other via TCP. The TCP one was failing for some reason,
with the following results.
Use of uninitialized value in subroutine entry at
/usr/lib/perl5/Net/DNS/Packet.pm line 588.
Exception: corrupt or incomplete data at /usr/lib/perl5/Net/DNS/RR.pm line
510.
caught at -e line 1
This error was being triggered when I called the "print" method on a packet
generated with the following code.
# ...snipped code that reads $data...
$packet = Net::DNS::Packet->new(\$data);
undef($data);
In an attempt to diagnose this, I added the "debug" parameter to the new()
call (i.e. $packet = Net::DNS::Packet->new(\$data, 1)), and the problem
immediately vanished, which was odd. I then determined that my working UDP
code continued to work (and my TCP code continued to fail) when the data
being passed to new() was *exactly the same*. This was completely baffling.
My suspicion subsequently fell on the following undef() command, which was
being used to free up the data buffer explicitly. I was not doing this in my
UDP code, but allowing the buffer to be freed when it went out of scope.
Removing this undef() cleared the problem.
Hypothesis: there has been some kind of oversight in reference counting in
XS code. My undef($data) is reducing the reference count to zero, but
Net::DNS still has a pointer to the data somewhere. The complaint about
"corrupt or incomplete data" is happening because the data is in
partly-overwritten freed memory, which should not be referenced.