id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 12837,Binary serialization: crash that may allow jump to attacker-controlled address,jepler@…,Robert Ramey,"Using afl-fuzz on some simple programs that use boost binary and xml serialization, I have found a number of crashes and assertion failures. To test the waters, I am beginning by filing a single bug which may allow a jump to an attacker-controlled address (i.e., the most exploitable-looking crash that has turned up so far). On my test system, it crashes on the instruction shown: {{{ => 0x000000000044849c <+524>: mov (%r12),%rax 0x00000000004484a0 <+528>: mov 0x20(%rbp),%r15d 0x00000000004484a4 <+532>: mov %r12,%rdi 0x00000000004484a7 <+535>: callq *0x10(%rax) }}} Notice that the value loaded at instruction <+524> is used to determine the address to call at instruction <+535>. The value of %r12 interpreted as bytes is ""\0\0hive\0\0"", which makes me strongly suspect that it is data from the input file (part of the 'serialization::archive' signature, masked off). Generally, the whole text of the input file would be considered under the control of the adversary. I ran my tests on Debian Jessie amd64 with gcc version 4.9.2 (Debian 4.9.2-10). The following revisions of modularized boost were used (the tip of each master branch at the time of writing, as described by 'git describe --tags --always): {{{ config: boost-1.62.0-57-g1abc59c core: boost-1.61.0-59-gd753d9a move: boost-1.63.0 serialization: boost-1.61.0-57-g62bf8fc }}} The commandline to compile the (non-fuzzing) version of the input test program is: {{{ g++-4.9 -std=c++11 -Os -I serialization/include -I core/include -I move/include -I config/include -o pvec_in pvec_in.cc serialization/src/extended_type_info.cpp serialization/src/extended_type_info_typeid.cpp serialization/src/archive_exception.cpp serialization/src/basic_archive.cpp serialization/src/basic_serializer_map.cpp serialization/src/void_cast.cpp serialization/src/singleton.cpp serialization/src/basic_iarchive.cpp serialization/src/binary_iarchive.cpp serialization/src/basic_iserializer.cpp serialization/src/basic_pointer_iserializer.cpp }}} The breaking input file is (base-64 encoded): {{{ FgAAAAAAAABzZXJpYWxpemF0aW9uOjphcmNoaXZlDwAECAQIAQAAAAAAAAAAAwAAAAAAAAABAAAA AAEAAAD0/wEAAAAAAAAAAAEAAAACAAEAAAACAAAAAgAAAAAA }}} The source for the test harness program (pvec_in.cc) is {{{ #include #include #include #include #include #include #include struct boxed_int { boxed_int() : i(0) {} boxed_int(int i) : i(i) {} int i; template void serialize(Archive &ar, unsigned version) { ar & BOOST_SERIALIZATION_NVP(i); } }; typedef boost::shared_ptr pi; void go(std::istream &is) { std::vector vv; try { boost::archive::binary_iarchive ia(is); ia & vv; } catch(std::exception &e) {} } int main(int argc, char **argv) { if(argc > 1) { std::ifstream is(argv[1]); go(is); } else { go(std::cin); } return 0; } }}} The test harness program either takes the input file on stdin or the name of the input file as the first positional argument. I can share details about the fuzzing setup if you like. Thank you for taking the time to consider this issue. --Jeff",Bugs,assigned,To Be Determined,serialization,Boost Development Trunk,Problem,,security,jepler@…