Opened 9 years ago

Closed 8 years ago

#9940 closed Bugs (fixed)

bad bug in intrusive list with safe_link (or auto_unlink) hooks

Reported by: Matei David <matei@…> Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: intrusive
Version: Boost 1.55.0 Severity: Problem
Keywords: intrusive list safe_link Cc:

Description

Looking at class list_impl inside list.hpp:

  • the header node is stored as a data member somewhere inside list_impl::data_;
  • however, the class inherits from detail::clear_on_destructor_base.

This is really bad. During destruction, the header is deallocated first (as a data member), and after, the destructor of clear_on_destructor_base attempts to clear the list.

To replicate the bug, use safe_link hooks, and have the node/value destructor clear the list pointers. The base class destructor calls clear(), which calls clear_and_dispose(), which forms iterator it by following the header pointer (which is zeroed by then). Incrementing it results in SEGV.

The same probably happens with auto_unlink hooks which also trigger post-mortem destruction from the base class.

Attachments (1)

bi-list-bug.cpp (1.0 KB ) - added by Matei David <matei@…> 9 years ago.
demonstrates bug

Download all attachments as: .zip

Change History (3)

by Matei David <matei@…>, 9 years ago

Attachment: bi-list-bug.cpp added

demonstrates bug

comment:1 by Matei David <matei@…>, 8 years ago

Correction: "During destruction, the header is destructed (not deallocated) first".

In practice, "chances are" the bug will be observed only if the value/node destructor is not trivial.

In theory, the code triggers undefined behaviour the moment the destructor of detail::clear_on_destructor_base calls Derived::clear(), because data members of Derived (list_impl in this case) are already destructed at that point.

comment:2 by Ion Gaztañaga, 8 years ago

Resolution: fixed
Status: newclosed

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:

[develop d7212a1] Fixed #9940 ("bad bug in intrusive list with safe_link (or auto_unlink) hooks")

6 files changed, 103 insertions(+), 134 deletions(-) delete mode 100644 include/boost/intrusive/detail/clear_on_destructor_base.hpp

Note: See TracTickets for help on using tickets.