[libc++] Fix use-after-free when building with _LIBCPP_DEBUG=1
authorThomas Anderson <thomasanderson@google.com>
Wed, 6 Mar 2019 21:10:08 +0000 (21:10 +0000)
committerThomas Anderson <thomasanderson@google.com>
Wed, 6 Mar 2019 21:10:08 +0000 (21:10 +0000)
commit516d07de071114f24ebcd51b629df70d02f1398a
treeb7444bbb70efd2745afe3001ecb9e9daddd225be
parent3161c89a22f97b14c82db589d593e9da8379395f
[libc++] Fix use-after-free when building with _LIBCPP_DEBUG=1

The issue is the following code:

    __cn1->__add(*__ip);
    (*__ip)->__c_ = __cn1;

`__ip` points into the array of iterators for container `__cn2`.  This code adds
the iterator to the array of iterators for `__cn1`, and updates the iterator to
point to the new container.

This code works fine, except when `__cn1` and `__cn2` are the same container.
`__cn1->__add()` might need to grow the array of iterators, and when it does,
`__ip` becomes invalid, so the second line becomes a use-after-free error.

Simply swapping the order of the above two lines is not sufficient, because of
the memmove() below.  The easiest and most performant solution is just to skip
touching any iterators if the containers are the same.

Differential Revision: https://reviews.llvm.org/D58926

llvm-svn: 355550
libcxx/include/list
libcxx/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp