Boost C++ Libraries: Ticket #9940: bad bug in intrusive list with safe_link (or auto_unlink) hooks https://svn.boost.org/trac10/ticket/9940 <p> Looking at <code>class list_impl</code> inside <code>list.hpp</code>: </p> <ul><li>the header node is stored as a data <strong>member</strong> somewhere inside <code>list_impl::data_</code>; </li><li>however, the class <strong>inherits</strong> from <code>detail::clear_on_destructor_base</code>. </li></ul><p> This is really bad. During destruction, the header is deallocated first (as a data member), and after, the destructor of <code>clear_on_destructor_base</code> attempts to clear the list. </p> <p> To replicate the bug, use <code>safe_link</code> hooks, and have the node/value destructor clear the list pointers. The base class destructor calls <code>clear()</code>, which calls <code>clear_and_dispose()</code>, which forms iterator <code>it</code> by following the header pointer (which is zeroed by then). Incrementing <code>it</code> results in SEGV. </p> <p> The same probably happens with <code>auto_unlink</code> hooks which also trigger post-mortem destruction from the base class. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9940 Trac 1.4.3 Matei David <matei@…> Wed, 23 Apr 2014 06:12:24 GMT attachment set https://svn.boost.org/trac10/ticket/9940 https://svn.boost.org/trac10/ticket/9940 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">bi-list-bug.cpp</span> </li> </ul> <p> demonstrates bug </p> Ticket Matei David <matei@…> Wed, 23 Apr 2014 18:48:50 GMT <link>https://svn.boost.org/trac10/ticket/9940#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9940#comment:1</guid> <description> <p> Correction: "During destruction, the header is <em>destructed</em> (not <em>deallocated</em>) first". </p> <p> In practice, "chances are" the bug will be observed only if the value/node destructor is not trivial. </p> <p> In theory, the code triggers undefined behaviour the moment the destructor of <code>detail::clear_on_destructor_base</code> calls <code>Derived::clear()</code>, because data members of <code>Derived</code> (<code>list_impl</code> in this case) are already destructed at that point. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Thu, 24 Apr 2014 08:50:34 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/9940#comment:2 https://svn.boost.org/trac10/ticket/9940#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Thanks for the report. I've removed the clear_on_destructor_base class, and performed cleanup on base classes (when insertions can lead to exceptions, such as trees and unordered containers with throwing comparators), or inside the container destructor (when insertions can't throw, like in list and slist). Fixed in commit: </p> <p> [develop d7212a1] Fixed <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9940" title="#9940: Bugs: bad bug in intrusive list with safe_link (or auto_unlink) hooks (closed: fixed)">#9940</a> ("bad bug in intrusive list with safe_link (or auto_unlink) hooks") </p> <blockquote> <p> 6 files changed, 103 insertions(+), 134 deletions(-) delete mode 100644 include/boost/intrusive/detail/clear_on_destructor_base.hpp </p> </blockquote> Ticket