Opened 12 years ago

Last modified 11 years ago

#4635 new Bugs

segmentation fault in text_oarchive::save_binary()

Reported by: Mark Heuser <mlheuser@…> Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost 1.43.0 Severity: Problem
Keywords: Cc:

Description

It appears that text_oarchive::save_binary() reads one byte too many. In other words, save_binary(addr,len) appears to read byte addr+len. The attached program, which runs on Linux, allocates a page of zeroes with mmap(2) and then serializes the last few bytes of the page with text_oarchive::save_binary(). The result is a segmentation fault.

Attachments (1)

save_binary_bug.cpp (1.1 KB ) - added by Mark Heuser <mlheuser@…> 12 years ago.
Linux/C++ program.

Download all attachments as: .zip

Change History (4)

by Mark Heuser <mlheuser@…>, 12 years ago

Attachment: save_binary_bug.cpp added

Linux/C++ program.

comment:1 by Robert Ramey, 12 years ago

a very good example/test. As you mention - a very, very deep stack.

Could you re-run the test with some counts which are mod 3? That is 3, 6, 9, ...

I develop on a windows system and it would be easier to ask you to just re-run the test rather than try to recreate it here.

Robert Ramey

comment:2 by mlheuser@…, 12 years ago

Robert,

You are on to something. Multiples of three work fine. If there is anything else that I can do to help, don't hesitate to ask.

-Mark

comment:3 by Aliaksei Plashchanski <alekseyploschanskiy@…>, 11 years ago

I met the same issue, i debugged and found that problem is in implementation base64_from_binary. Access violation appears in file transform_width.hpp. When iterator points to the last valid byte (addr+len-1) and algorithm need one more byte to complete missing bits - it increments iterator and read after buffer.

template<class Base, int BitsOut, int BitsIn, class CharType>
CharType transform_width<Base, BitsOut, BitsIn, CharType>::fill(){
    CharType retval = 0;
    unsigned int missing_bits = BitsOut;
    for(;;){
        unsigned int bcount;
        if(! m_bufferfull){
            m_buffer = * this->base_reference();  !!! access to byte *(addr+len)
            m_bufferfull = true;
            bcount = BitsIn;
        }
        else
            bcount = BitsIn - m_displacement;
        unsigned int i = (std::min)(bcount, missing_bits);
        // shift interesting bits to least significant position
        unsigned int j = m_buffer >> (bcount - i);
        // strip off uninteresting bits
        // (note presumption of two's complement arithmetic)
        j &= ~(-(1 << i));
        // append then interesting bits to the output value
        retval <<= i;
        retval |= j;
        missing_bits -= i;
        if(0 == missing_bits)
            break;
        // note: suspect that this is not invoked for borland 5.51
        ++(this->base_reference());
        m_bufferfull = false;
    }
    return retval;
}
Note: See TracTickets for help on using tickets.