Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#7745 closed Patches (invalid)

text_iarchive crashes on invalid data

Reported by: anonymous Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost 1.52.0 Severity: Problem
Keywords: Cc: ivagulin@…

Description

Following code randomly trigger OOM if "in" parameter not starting with number.

template <typename Type>
void
from_string(const std::string in, Type &out)
{
    std::stringstream ss(in);
    boost::archive::text_iarchive ia(ss);
    ia >> boost::serialization::make_nvp("obj", out);
}

This is linux box(gcc compiler and libstdc++) so real allocation starts in memset, not in new. Here is backtrace which cause it.

#0  0x0000003a48c7a203 in memset () from /lib64/libc.so.6
#1  0x0000003fa449cce2 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::append(unsigned long, char) () from /usr/lib64/libstdc++.so.6
#2  0x00002aaaaab03b89 in resize (this=0x7fffffffe3a0, s="")
    at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/basic_string.h:629
#3  boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::load (
    this=0x7fffffffe3a0, s="") at ./boost/archive/impl/text_iarchive_impl.ipp:55
#4  0x00002aaaaab03c44 in load_primitive<boost::archive::text_iarchive, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (this=0x2aab59734fb0)
    at ./boost/archive/detail/iserializer.hpp:107
#5  invoke<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
    this=0x2aab59734fb0) at ./boost/archive/detail/iserializer.hpp:338
#6  invoke<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
    this=0x2aab59734fb0) at ./boost/archive/detail/iserializer.hpp:415
#7  load<boost::archive::text_iarchive, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (this=0x2aab59734fb0) at ./boost/archive/detail/iserializer.hpp:554
#8  load_override<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
    this=0x2aab59734fb0) at ./boost/archive/detail/common_iarchive.hpp:61
#9  load_override<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
    this=0x2aab59734fb0) at ./boost/archive/basic_text_iarchive.hpp:62
#10 load_override<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
    this=0x2aab59734fb0) at ./boost/archive/text_iarchive.hpp:66
#11 operator>><std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
    this=0x2aab59734fb0) at ./boost/archive/detail/interface_iarchive.hpp:61
#12 boost::archive::basic_text_iarchive<boost::archive::text_iarchive>::init (
    this=0x2aab59734fb0) at ./boost/archive/impl/basic_text_iarchive.ipp:50
#13 0x00002aaaaab03fb8 in boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::text_iarchive_impl (this=0x7fffffffe3a0, is=<value optimized out>, flags=0)
    at ./boost/archive/impl/text_iarchive_impl.ipp:123
#14 0x000000000043fe16 in boost::archive::text_iarchive::text_iarchive (this=0x7fffffffe3a0, 
    is_=..., flags=0) at /usr/include/boost/archive/text_iarchive.hpp:115
#15 0x0000000000440549 in from_string<log_info_t> 

Attachments (1)

text-iarchive-crash.patch (678 bytes ) - added by ivagulin@… 10 years ago.
attached patch fixes problem for me

Download all attachments as: .zip

Change History (8)

comment:1 by ivagulin@…, 10 years ago

Cc: ivagulin@… added
Component: Noneserialization
Owner: set to Robert Ramey

by ivagulin@…, 10 years ago

Attachment: text-iarchive-crash.patch added

attached patch fixes problem for me

comment:2 by anonymous, 10 years ago

Type: BugsPatches

comment:3 by Robert Ramey, 10 years ago

There should be no need to initialize the size variable. Perhaps the archive file was corrupted in some way.

Robert Ramey

comment:4 by Igor Vagulin <ivagulin@…>, 10 years ago

Yes, archive was incorrect(it was "nonexistent-key", redis-cplusplus-client use it as mark of non existent key). I expect some kind of exception, but I get program which tries to allocate 230 of ram. With my patch I get std::bad_alloc. I believe it is much better behaviour.

Maybe my explanations not very clear. Here what I get step by step:

text_iarchive_impl<Archive>::load(std::string &s){

std::size_t size; here size set to some junk from stack, in my bad case it was -1

  • this->This() >> size; libstdc++, gcc4.4 didn't set size, it still ~230 is.get(); s.resize(size); allocation of size set to -1 ...

}

Only downside of this patch I can imagine is mostly unneeded initialization of variable, but:

  • I wasn't able to measure it
  • Increase in stability outweight this in my opinion

comment:5 by Igor Vagulin <ivagulin@…>, 10 years ago

Sorry for bad format, here it is properly formated.

text_iarchive_impl<Archive>::load(std::string &s){
    std::size_t size; //here size set to some junk from stack, in my bad case it was -1
    this->This() >> size; //libstdc++, gcc4.4 didn't set size, it still ~2**30
    is.get(); 
    s.resize(size); //allocation of size set to -1
    ... 
} 

comment:6 by Robert Ramey, 10 years ago

Resolution: invalid
Status: newclosed

comment:7 by Igor Vagulin <ivagulin@…>, 10 years ago

Can you please provide rationale for bug invalidation. Is there any better way to check for archive validity other than trying to extract object from it?

Note: See TracTickets for help on using tickets.