Skip to content

Heap buffer overflow in Polynomial: #156

Open
@NAThompson

Description

@NAThompson

Code to reproduce:

#include <iostream>
#include <vector>
#include <boost/math/tools/polynomial.hpp>

using boost::math::tools::polynomial;

template<class Real>
void problem(size_t N)
{
    std::vector<Real> coeffs(N);
    for (size_t i = 0; i < coeffs.size(); ++i) {
      coeffs[i] = i;
    }

    polynomial<Real> p(coeffs.data(), coeffs.size());

    std::cout << "Polynomial: " << p << std::endl;
}

int main()
{
    problem<double>(2);
}

Compile with AddressSanitizer:

$ clang++ --std=gnu++17 -O0 -g -fsanitize=address -fsanitize=undefined -Wall -Wfatal-errors -march=native main.cpp

Then:

=================================================================
==90840==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000120 at pc 0x00010b72a581 bp 0x7ffee44eef90 sp 0x7ffee44eef88
READ of size 8 at 0x602000000120 thread T0
    #0 0x10b72a580 in std::__1::enable_if<__is_forward_iterator<double const*>::value, void>::type std::__1::vector<double, std::__1::allocator<double> >::__construct_at_end<double const*>(double const*, double const*, unsigned long) vector:1030
    #1 0x10b729a4d in std::__1::vector<double, std::__1::allocator<double> >::vector<double const*>(double const*, std::__1::enable_if<(__is_forward_iterator<double const*>::value) && (is_constructible<double, std::__1::iterator_traits<double const*>::reference>::value), double const*>::type) vector:1178
    #2 0x10b726644 in std::__1::vector<double, std::__1::allocator<double> >::vector<double const*>(double const*, std::__1::enable_if<(__is_forward_iterator<double const*>::value) && (is_constructible<double, std::__1::iterator_traits<double const*>::reference>::value), double const*>::type) vector:1170
    #3 0x10b72656d in boost::math::tools::polynomial<double>::polynomial<double>(double const*, unsigned int) polynomial.hpp:292
    #4 0x10b71e300 in boost::math::tools::polynomial<double>::polynomial<double>(double const*, unsigned int) polynomial.hpp:293
    #5 0x10b711c00 in void problem<double>(unsigned long) main.cpp:21
    #6 0x10b7114b7 in main main.cpp:28
    #7 0x7fff6fc2b08c in start (libdyld.dylib:x86_64+0x1708c)

The constructor call should be polynomial<double> p(coeffs.data(), coeffs.size() -1), but this doesn't seem idiomatic to me. Is there any way we can assert on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions