Opened 4 years ago

Last modified 4 years ago

#13635 new Bugs

circular_buffer does not always initialize elements

Reported by: Niklas Fejes <niklas.fejes@…> Owned by: Jan Gaspar
Milestone: To Be Determined Component: circular_buffer
Version: Boost Development Trunk Severity: Problem
Keywords: Cc:

Description

The circular_buffer erroneously mark some sections of the buffer as initialized, which can lead to use of uninitialized memory for non-trivial classes in the insert function. The problem appears to come from the is_uninitialized function, which does not properly handle the buffer state when m_buff < m_first < m_last.

bool is_uninitialized(const_pointer p) const BOOST_NOEXCEPT {
    return p >= m_last && (m_first < m_last || p < m_first);
}

In this case, e.g. p = m_buff will be flagged as initialized since p >= m_last is false.

A proper check would be:

bool is_uninitialized(const_pointer p) const BOOST_NOEXCEPT {
    if (m_first < m_last)
        return p >= m_last || p < m_first;
    return p >= m_last && p < m_first;
}

Minimal reproducing program:

#include <vector>
#include <boost/circular_buffer.hpp>
/*
$ g++ --version | head -n1
g++ (GCC) 8.1.1 20180531
$ g++ example.cpp -o example && valgrind --tool=memcheck ./example 2>&1 | grep Invalid
==19349== Invalid write of size 8
==19349== Invalid write of size 2
==19349== Invalid free() / delete / delete[] / realloc()
*/
int main()
{
    std::vector<int> x(7), y(8); // has non-trivial move/copy
    boost::circular_buffer< std::vector<int> > buffer(3);
    buffer.push_back(x); //   [x| | ]
    buffer.push_back(x); //   [x|x| ]
    buffer.pop_front();  //   [ |x| ]
    buffer.insert(buffer.begin(), 2, y);
    // is_uninitialized(i) -> [0,0,1] (should be [1,0,1])
    // [copy      1 -> 0] :   [x|x| ] bad copy to uninitialized element
    // [copy      y -> 1] :   [x|y| ] ok
    // [construct y -> 2] :   [x|y|y] ok
    return 0; // tries to destruct uninitialized entry
}

Change History (1)

comment:1 by Niklas Fejes <niklas.fejes@…>, 4 years ago

Note: See TracTickets for help on using tickets.