BYVoid / OpenCC

Conversion between Traditional and Simplified Chinese
https://opencc.byvoid.com/
Apache License 2.0
8.49k stars 980 forks source link

Heap-Out-Of-Bound-Read in BinaryDict::NewFromFile() #813

Open morningbread opened 1 year ago

morningbread commented 1 year ago

Hi, i found a heap-out-of-bound-read vulnerability in BinaryDict::NewFromFile().

I put the POC in the attachment, prove it like this. (compile open_dict with address sanitizer). ./opencc_dict -i poc -o tmp -f ocd -t text

Then, ASAN would catch the error:

==3469586==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60800000017d at pc 0x0000004328d6 bp 0x7ffe0acc1eb0 sp 0x7ffe0acc1670                                                                                                 READ of size 1 at 0x60800000017d thread T0                                                                                
#0 0x4328d5 in __interceptor_strlen /home/brian/src/llvm_releases/llvm-project/llvm/utils/release/final/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:389:5                                      
#1 0x7fc34d5732a5 in std::char_traits<char>::length(char const*) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/char_traits.h:342:9                                                                                         
#2 0x7fc34d5732a5 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:531:39                                                                                                                 
#3 0x7fc34d5732a5 in opencc::BinaryDict::NewFromFile(_IO_FILE*) /home/coco/work/OpenCC/src/BinaryDict.cpp:135:24     
#4 0x7fc34d578430 in opencc::DartsDict::NewFromFile(_IO_FILE*) /home/coco/work/OpenCC/src/DartsDict.cpp:130:22        
#5 0x7fc34d508db4 in bool opencc::SerializableDict::TryLoadFromFile<opencc::DartsDict>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<opencc::DartsDict>*) /home/coco/work/OpenCC/src/SerializableDict.hpp:62:40                                                                                         
#6 0x7fc34d51e9a7 in std::shared_ptr<opencc::DartsDict> opencc::SerializableDict::NewFromFile<opencc::DartsDict>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/coco/work/OpenCC/src/SerializableDict.hpp:71:10                                                                                                    
#7 0x7fc34d51e9a7 in LoadDictionary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/coco/work/OpenCC/src/DictConverter.cpp:35:12                                                                                            
#8 0x7fc34d51f0f4 in opencc::ConvertDictionary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/coco/work/OpenCC/src/DictConverter.cpp:65:22
#9 0x4db5cf in main /home/coco/work/OpenCC/src/tools/DictConverter.cpp:48:5
#10 0x7fc34cf63082 in __libc_start_main /build/glibc-5hggjy/glibc-2.31/csu/../csu/libc-start.c:308:16
#11 0x41e81d in _start (/home/coco/work/OpenCC/build/rel/src/tools/opencc_dict+0x41e81d)

poc.zip