Skip Menu |

This queue is for tickets about the XML-LibXML CPAN distribution.

Report information
The Basics
Id: 94149
Status: resolved
Priority: 0/
Queue: XML-LibXML

People
Owner: Nobody in particular
Requestors: jeff [...] jefftrout.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: libxml2 optimization in xmlAddSibling leads to a double free in DESTROY.
Date: Mon, 24 Mar 2014 13:28:30 -0400
To: bug-XML-LibXML [...] rt.cpan.org
From: Jeff <jeff [...] jefftrout.com>
Been hitting a bug that randomly occurs, but always from the guts of XML::LibXML. however, I’ve never been able to reliably reproduce it until today. After debugging I was able to get to the root of the problem: In libxml2’s tree.c xmlAddSibling has an optimization where if the existing node is text and you are appendSibling a text node it will instead append the text onto the existing sibling then xmlFree the new sibling. When done via XML::LibXML this effectively free’s our xmlNode out from under us, then when DESTROY is run we end up with a double free, which can lead to all sorts of neat things. (In my case, it would sometimes lock up in the deep down in free()) Code to induce it is pretty simple: use strict; use XML::LibXML; my $orig = new XML::LibXML::Text("Double "); $orig->addSibling(new XML::LibXML::Text("Free")); valgrind output confirms: jeff@debian:~/insiderscore/site$ valgrind perl doublefree.pl ==13673== Memcheck, a memory error detector ==13673== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==13673== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==13673== Command: perl doublefree.pl ==13673== ==13673== Invalid read of size 8 ==13673== at 0x6C798C8: PmmREFCNT_dec (perl-libxml-mm.c:448) ==13673== by 0x6C5DB3E: XS_XML__LibXML__Node_DESTROY (LibXML.xs:4147) ==13673== by 0x4EE764B: Perl_pp_entersub (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x4E7AAD0: Perl_call_sv (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x4EEDB18: Perl_sv_clear (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x4EEE1D1: Perl_sv_free2 (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x4F139BF: Perl_free_tmps (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x4E80633: perl_run (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x400F88: main (in /usr/bin/perl) ==13673== Address 0x7701380 is 0 bytes inside a block of size 120 free'd ==13673== at 0x4C27D4E: free (vg_replace_malloc.c:427) ==13673== by 0x6EF0CC2: xmlAddSibling (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.8.0) ==13673== by 0x6C5ACE5: XS_XML__LibXML__Node_addSibling (LibXML.xs:5041) ==13673== by 0x4EE764B: Perl_pp_entersub (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x4EDEC25: Perl_runops_standard (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x4E80754: perl_run (in /usr/lib/libperl.so.5.14.2) ==13673== by 0x400F88: main (in /usr/bin/perl) ==13673== I’ve updated my application to detect this scenario and turn it into an append rather than addSibling, however XML::LibXML may want to add a check for that as well. -- Jeff Trout <jeff@jefftrout.com>
On Wed Mar 26 13:10:19 2014, NWELLNHOF wrote: Show quoted text
> Fixed in this pull request: > > https://bitbucket.org/shlomif/perl-xml-libxml/pull-request/30/fix- > double-free-when-calling-node/diff > > Thanks for the report. > > Nick
Thanks for the report and the bug fix. I'm RESOLVED-ing this bug report. Nick, I should note that seeing your recent pull requests were perfectly fine, I gave you a commit/"write" bit for the perl-xml-libxml repository: https://bitbucket.org/shlomif/perl-xml-libxml Enjoy! Regards, -- Shlomi Fish