Double Free in opusfile
As part of our fuzzing efforts at Google, we have identified an issue in git HEAD of opusfile. To reproduce requires compiling the project with the LLVM compiler, taking advantage of the sanitizers that it offers (this issue was discovered using AddressSanitizer.
To reproduce you will need to build your project using that sanitizer, and execute the attached stub code on the reproducer input that we have also provided. This stub code could also serve as a useful template for fuzzing in your project with llibFuzzer and/or AFL, which may help you uncover additional issues. Some documentation on how to get started with libFuzzer is here:
The following options / environment variables may be necessary for accurate reproduction of the issue as well:
ASAN_OPTIONS="exitcode=1,handle_segv=1,detect_leaks=1,leak_check_at_exit=1,a
llocator_may_return_null=1,detect_odr_violation=0"
MSAN_OPTIONS=...
}}}
The sanitizer error that we encountered is here:
{{{
==779726==ERROR: LeakSanitizer: detected memory leaks
SUMMARY: AddressSanitizer: 78 byte(s) leaked in 4 allocation(s).
}}}
Other relevant info/repro instructions:
{{{
** Repro:
git clone https://git.xiph.org/opusfile.git
sudo apt-get install libogg-dev libopus-dev
CC="clang-3.8" CFLAGS="-O1 -g -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,return,returns-nonnull-attribute,shift-exponent,unreachable,vla-bound -fno-sanitize-recover=all -fno-omit-frame-pointer -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1" CXX="clang++-3.8" CXXFLAGS="-O1 -g -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,return,returns-nonnull-attribute,shift-exponent,unreachable,vla-bound -fno-sanitize-recover=all -fno-omit-frame-pointer -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1" LDFLAGS="-g -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,return,returns-nonnull-attribute,shift-exponent,unreachable,vla-bound" ./configure && make
./examples/opusfile_example ./34286806_leak-c99edf095c8159361c13c868fbf7b257371a4007-min
** Analysis:
The issue is in src/info.c.
This call to opus_tags_parse_impl() fails, and opus_tags_clear() is called:
226 ret=opus_tags_parse_impl(&tags,_data,_len);
227 if(ret<0)opus_tags_clear(&tags);
It fails at this line:
192 _data+=4;
193 len-=4;
194 if(count>len)return OP_EBADHEADER;
because count = 0x43000026 and length = 0x26.
Then at this line:
99 for(ci=ncomments;ci-->0;)_ogg_free(_tags->user_comments[ci]);
It frees memory that I don't think was ever allocated:
_tags->user_comments[ci] => 0xbebebebebebebebe
We will gladly work with you so you can successfully confirm and reproduce this issue. Do let us know if you have any feedback surrounding the documentation.
Once you have reproduced the issue, we’d appreciate to learn your expected timeline for an update to be released. With any fix, please attribute the report to “Google Autofuzz project”.
We are also pleased to inform you that your project is also eligible for inclusion to the OSS-Fuzz project, which can provide additional continuous fuzzing, and encourage you to investigate [https://github.com/google/oss- fuzz/blob/master/docs/new_project_guide.md integration options].
Don’t hesitate to let us know if you have any questions!
Google AutoFuzz Team