Closed GeoffWilliams closed 8 years ago
Thanks for the excellent and thorough bug report. Having that made fixing this bug really easy. I'll leave the PR open for a couple days to give you chance to test it - if you do, lmk if it really does fix the issue.
NP! PR fixes issue
Overview
Double free from libaugeas with lens
Xml.lns
when deleting nested XML elements collected using//
(descendant-or-self).Software versions
background
Augeas is being used to remove all
Realm
elements from Tomcat'sserver.xml
file using theruby-augeas
API like this:The operation itself seems to succeed but there is an error from
libaugeas
when the library attempts to free the memory being used.Originally this problem was encountered invoking augeas through Puppet but I was able to reproduce the problem using
augtool
, see testcase.External bug report: https://tickets.puppetlabs.com/browse/MODULES-1721
Error details
The above Ruby function enters libaugeas in
aug_rm()
and results in the following backtrace when running under puppet:Once I'd developed a stand-alone testcase I was able to add some print statements and step through the code with GDB and I found that:
free_tree_node()
whenfree()
is used against a dangling pointerfree_tree_node(del)
and recompile the library code works as expected but will leak memoryRealm
elements are built, one for each present in the input XML filetree_rm()
making a call totree_unlink_raw(del[i])
free_tree_node()
and the pointer value matches an element inside one of the previous treesNarrative (added
printf
statements)Root cause
Inside the XML file, I see the following
Realm
elements:It seems the parser has mapped the exact same memory for elements of the
struct tree
member being passed totree_unlink_raw()
which makes sense because the elements are nestedTestcase
assuming
testcase.xml
present on system at/vagrant/testcase.xml
and with a freshly compiled libaugeas from git, free of any source modifications:In the second testcase, I've un-nested the elements and Augeas is able to remove them with no problems:
How to fix this?
I'm not immediately clear on how this can be fixed being new to the internals of Augeas.
Looking at the nesting of the elements I'm trying to delete, the pointer structure I'm seeing makes sense since its the exact same XML nodes inside one another. I had been working under the assumption that the code was copying an object by reference instead of cloning it but clearly the parsing code is correct and not at fault.
It looks like the trees passed for deletion in
tree_rm()
need to be de-duplicated somehow, so that we don't try to delete nodes that are contained within a parent tree that has already been deleted - but I'm not sure of the best way to do this, can anyone help?Thanks! testcase.xml.txt testcase2.xml.txt