heap-use-after-free/SEGV/heap-buffer-overflow in UncompressedImageCodec::decode_uncompressed_image
Version
commit: 64ece913266609789f5dc70fe7de9eb759badd7f
heif-convert libheif version: 1.17.5
-------------------------------------------
Usage: heif-convert [options] <input-image> [output-image]
The program determines the output file format from the output filename suffix.
These suffixes are recognized: jpg, jpeg, png, y4m. If no output filename is specified, 'jpg' is used.
Options:
-h, --help show help
-v, --version show version
-q, --quality quality (for JPEG output)
-o, --output FILENAME write output to FILENAME (optional)
-d, --decoder ID use a specific decoder (see --list-decoders)
--with-aux also write auxiliary images (e.g. depth images)
--with-xmp write XMP metadata to file (output filename with .xmp suffix)
--with-exif write EXIF metadata to file (output filename with .exif suffix)
--skip-exif-offset skip EXIF metadata offset bytes
--no-colons replace ':' characters in auxiliary image filenames with '_'
--list-decoders list all available decoders (built-in and plugins)
--quiet do not output status messages to console
-C, --chroma-upsampling ALGO Force chroma upsampling algorithm (nn = nearest-neighbor / bilinear)
--png-compression-level # Set to integer between 0 (fastest) and 9 (best). Use -1 for default.
Replay
cd libheif
mkdir build && cd build
CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address" cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_UNCOMPRESSED_CODEC=ON ..
make -j
./examples/heif-convert ./poc test.png
ASAN
I just show the bof case, you can use my poc to reproduce the others.
=================================================================
==88945==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x613000000528 at pc 0x7fd270526821 bp 0x7ffc3ade57f0 sp 0x7ffc3ade57e0
READ of size 1 at 0x613000000528 thread T0
#0 0x7fd270526820 in UncompressedImageCodec::decode_uncompressed_image(std::shared_ptr<HeifFile const> const&, unsigned int, std::shared_ptr<HeifPixelImage>&, unsigned int, unsigned int, std::vector<unsigned char, std::allocator<unsigned char> > const&) libheif/libheif/uncompressed_image.cc:784
#1 0x7fd2703e5304 in HeifContext::decode_image_planar(unsigned int, std::shared_ptr<HeifPixelImage>&, heif_colorspace, heif_decoding_options const&, bool) const libheif/libheif/context.cc:1452
#2 0x7fd2703e22a8 in HeifContext::decode_image_user(unsigned int, std::shared_ptr<HeifPixelImage>&, heif_colorspace, heif_chroma, heif_decoding_options const&) const libheif/libheif/context.cc:1248
#3 0x7fd2703a51f4 in heif_decode_image libheif/libheif/heif.cc:1044
#4 0x5590cf2fca11 in main libheif/examples/heif_convert.cc:484
#5 0x7fd26fe1d082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
#6 0x5590cf2f7add in _start (libheif/build/examples/heif-convert+0xbadd)
0x613000000528 is located 30 bytes to the right of 330-byte region [0x6130000003c0,0x61300000050a)
allocated by thread T0 here:
#0 0x7fd2706f4258 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.4+0xe1258)
#1 0x5590cf2f97b4 in __gnu_cxx::new_allocator<unsigned char>::allocate(unsigned long, void const*) /usr/include/c++/7/ext/new_allocator.h:111
#2 0x5590cf2f9286 in std::allocator_traits<std::allocator<unsigned char> >::allocate(std::allocator<unsigned char>&, unsigned long) /usr/include/c++/7/bits/alloc_traits.h:436
#3 0x5590cf2f8fb5 in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_allocate(unsigned long) /usr/include/c++/7/bits/stl_vector.h:172
#4 0x5590cf2f8864 in std::vector<unsigned char, std::allocator<unsigned char> >::_M_default_append(unsigned long) /usr/include/c++/7/bits/vector.tcc:571
#5 0x5590cf2f84c6 in std::vector<unsigned char, std::allocator<unsigned char> >::resize(unsigned long) /usr/include/c++/7/bits/stl_vector.h:692
#6 0x7fd27032e7ff in Box_iloc::read_data(Box_iloc::Item const&, std::shared_ptr<StreamReader> const&, std::shared_ptr<Box_idat> const&, std::vector<unsigned char, std::allocator<unsigned char> >*) const libheif/libheif/box.cc:1252
#7 0x7fd2704238bc in HeifFile::get_compressed_image_data(unsigned int, std::vector<unsigned char, std::allocator<unsigned char> >*) const libheif/libheif/file.cc:900
#8 0x7fd2703e50f9 in HeifContext::decode_image_planar(unsigned int, std::shared_ptr<HeifPixelImage>&, heif_colorspace, heif_decoding_options const&, bool) const libheif/libheif/context.cc:1448
#9 0x7fd2703e22a8 in HeifContext::decode_image_user(unsigned int, std::shared_ptr<HeifPixelImage>&, heif_colorspace, heif_chroma, heif_decoding_options const&) const libheif/libheif/context.cc:1248
#10 0x7fd2703a51f4 in heif_decode_image libheif/libheif/heif.cc:1044
#11 0x5590cf2fca11 in main libheif/examples/heif_convert.cc:484
#12 0x7fd26fe1d082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
Description
heap-use-after-free/SEGV/heap-buffer-overflow in
UncompressedImageCodec::decode_uncompressed_image
Version
Replay
ASAN
POC
Environment
Credit
Yuchuan Meng (Fudan University)