Opened 3 months ago

Closed 3 weeks ago

#8960 closed defect (fixed)

The function decode_frame in libavcodec/tiff.c has an uninitialized variable which may cause application crash

Reported by: 1vanChen Owned by:
Priority: important Component: avcodec
Version: git-master Keywords: tif crash regression
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

commit ae9a1a96982669926a4ecb92b066814f5f27dc38

$ ./ffmpeg_AV_CODEC_ID_TIFF_fuzzer_asan poc1
======================= INFO =========================
This binary is built for AFL-fuzz.
To run the target function on individual input(s) execute this:
  ./ffmpeg_AV_CODEC_ID_TIFF_fuzzer_asan < INPUT_FILE
or
  ./ffmpeg_AV_CODEC_ID_TIFF_fuzzer_asan INPUT_FILE1 [INPUT_FILE2 ... ]
To fuzz with afl-fuzz execute this:
  afl-fuzz [afl-flags] ./ffmpeg_AV_CODEC_ID_TIFF_fuzzer_asan [-N]
afl-fuzz will run N iterations before re-spawning the process (default: 1000)
======================================================
Reading 21170 bytes from poc1
AddressSanitizer:DEADLYSIGNAL
=================================================================
==13995==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x0000006674d1 bp 0x7ffc9154b5c0 sp 0x7ffc9154b5a0 T0)
==13995==The signal is caused by a READ memory access.
==13995==Hint: address points to the zero page.
    #0 0x6674d1 in bytestream_get_be32 /src/ffmpeg/libavcodec/bytestream.h:96:1
    #1 0x6674d1 in bytestream2_get_be32u /src/ffmpeg/libavcodec/bytestream.h:96:1
    #2 0x6674d1 in bytestream2_get_be32 /src/ffmpeg/libavcodec/bytestream.h:96:1
    #3 0x6674d1 in ff_tget_long /src/ffmpeg/libavcodec/tiff_common.c:51:44
    #4 0x668b14 in ff_tget /src/ffmpeg/libavcodec/tiff_common.c:67:29
    #5 0x6006e3 in decode_frame /src/ffmpeg/libavcodec/tiff.c:2002:25
    #6 0x523428 in decode_simple_internal /src/ffmpeg/libavcodec/decode.c:352:15
    #7 0x52257e in decode_simple_receive_frame /src/ffmpeg/libavcodec/decode.c:556:15
    #8 0x4f75c4 in decode_receive_frame_internal /src/ffmpeg/libavcodec/decode.c:576:15
    #9 0x4f6e9e in avcodec_send_packet /src/ffmpeg/libavcodec/decode.c:634:15
    #10 0x4fcadb in compat_decode /src/ffmpeg/libavcodec/decode.c:769:15
    #11 0x4d40dc in LLVMFuzzerTestOneInput /src/ffmpeg/tools/target_dec_fuzzer.c:338:23
    #12 0x1749bea in main (/mnt/disk/out/ffmpeg-single/ffmpeg_AV_CODEC_ID_TIFF_fuzzer_asan+0x1749bea)
    #13 0x7fe3803f783f in __libc_start_main /build/glibc-e6zv40/glibc-2.23/csu/../csu/libc-start.c:291
    #14 0x41e198 in _start (/mnt/disk/out/ffmpeg-single/ffmpeg_AV_CODEC_ID_TIFF_fuzzer_asan+0x41e198)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /src/ffmpeg/libavcodec/bytestream.h:96:1 in bytestream_get_be32
==13995==ABORTING

Compilation parameters:

#!/bin/bash -eux
export CC="/afl/afl-clang-fast"
export CXX="/afl/afl-clang-fast++"
export CFLAGS="-pthread -Wl,--no-as-needed -Wl,-ldl -Wl,-lm -Wno-unused-command-line-argument -O3"
export CXXFLAGS="-stdlib=libc++ -pthread -Wl,--no-as-needed -Wl,-ldl -Wl,-lm -Wno-unused-command-line-argument -O3"
export LIB_FUZZING_ENGINE="/libAFLDriver.a"
export ARCHITECTURE="x86_64"

export CFLAGS="$CFLAGS -fno-sanitize=vptr"
export CXXFLAGS="$CXXFLAGS -fno-sanitize=vptr"

#add llvm-coverage
export CFLAGS="$CFLAGS -fprofile-instr-generate -fcoverage-mapping"
export CXXFLAGS="$CXXFLAGS -fprofile-instr-generate -fcoverage-mapping"

# Build dependencies.
export FFMPEG_DEPS_PATH=$SRC/ffmpeg_deps
mkdir -p $FFMPEG_DEPS_PATH

export PATH="$FFMPEG_DEPS_PATH/bin:$PATH"
export LD_LIBRARY_PATH="$FFMPEG_DEPS_PATH/lib"


export AFL_LLVM_LAF_SPLIT_SWITCHES=1
export AFL_LLVM_LAF_SPLIT_COMPARES=1


cd $SRC
bzip2 -f -d alsa-lib-*
tar xf alsa-lib-*
cd alsa-lib-*
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/fdk-aac
autoreconf -fiv
CXXFLAGS="$CXXFLAGS -fno-sanitize=shift-base,signed-integer-overflow" \
./configure --prefix="$FFMPEG_DEPS_PATH" --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/libXext
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc)
make install

cd $SRC/libXfixes
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc)
make install

cd $SRC/libva
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/libvdpau
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/libvpx
LDFLAGS="$CXXFLAGS" ./configure --prefix="$FFMPEG_DEPS_PATH" \
    --disable-examples --disable-unit-tests \
    --size-limit=12288x12288 \
    --extra-cflags="-DVPX_MAX_ALLOCABLE_MEMORY=1073741824"
make clean
make -j$(nproc) all
make install

cd $SRC/ogg
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-crc
make clean
make -j$(nproc)
make install

cd $SRC/opus
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc) all
make install

cd $SRC/theora
# theora requires ogg, need to pass its location to the "configure" script.
CFLAGS="$CFLAGS -fPIC" LDFLAGS="-L$FFMPEG_DEPS_PATH/lib/" \
    CPPFLAGS="$CXXFLAGS -I$FFMPEG_DEPS_PATH/include/" \
    LD_LIBRARY_PATH="$FFMPEG_DEPS_PATH/lib/" \
    ./autogen.sh
./configure --with-ogg="$FFMPEG_DEPS_PATH" --prefix="$FFMPEG_DEPS_PATH" \
    --enable-static --disable-examples
make clean
make -j$(nproc)
make install

cd $SRC/vorbis
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc)
make install

# Remove shared libraries to avoid accidental linking against them.
rm $FFMPEG_DEPS_PATH/lib/*.so
rm $FFMPEG_DEPS_PATH/lib/*.so.*

export AFL_USE_ASAN=1
cd $SRC/ffmpeg
make clean
PKG_CONFIG_PATH="$FFMPEG_DEPS_PATH/lib/pkgconfig" ./configure \
    --cc=$CC --cxx=$CXX --ld="$CXX $CXXFLAGS -std=c++11" \
    --extra-cflags="-I$FFMPEG_DEPS_PATH/include" \
    --extra-ldflags="-L$FFMPEG_DEPS_PATH/lib" \
    --extra-ldflags="-L/afl/" \
    --prefix="$FFMPEG_DEPS_PATH" \
    --pkg-config-flags="--static" \
    --libfuzzer=$LIB_FUZZING_ENGINE \
    --optflags=-O1 \
    --enable-gpl \
    --enable-libass \
    --enable-libfdk-aac \
    --enable-libfreetype \
    --enable-libopus \
    --enable-libtheora \
    --enable-libvorbis \
    --enable-libvpx \
    --enable-nonfree \
    --disable-muxers \
    --disable-protocols \
    --disable-demuxer=rtp,rtsp,sdp \
    --disable-devices \
    --disable-shared --enable-cross-compile 
make clean
make -j$(nproc) install

# Build the fuzzers.
cd $SRC/ffmpeg

FUZZ_TARGET_SOURCE=$SRC/ffmpeg/tools/target_dec_fuzzer.c

export TEMP_VAR_CODEC="TIFF"
export TEMP_VAR_CODEC_TYPE="VIDEO"


# Build fuzzers for decoders.
fuzzer_name=ffmpeg_AV_CODEC_ID_${TEMP_VAR_CODEC}_fuzzer
symbol=`echo $TEMP_VAR_CODEC | sed "s/.*/\L\0/"`
make tools/target_dec_${symbol}_fuzzer
mv tools/target_dec_${symbol}_fuzzer $OUT/${fuzzer_name}_asan

Credit: 1vanChen of NSFOCUS Security Team

Attachments (1)

poc1 (20.7 KB) - added by 1vanChen 3 months ago.

Download all attachments as: .zip

Change History (7)

Changed 3 months ago by 1vanChen

comment:1 Changed 3 months ago by 1vanChen

  • Status changed from new to open

When s->is_tiled=1 , the initialization of the variable stripdata will be skipped. The function ff_tget will crash.

comment:2 follow-ups: Changed 2 months ago by cehoyos

  • Keywords tif added

Is this issue reproducible with ffmpeg, the application?

comment:3 in reply to: ↑ 2 Changed 2 months ago by 1vanChen

Replying to cehoyos:

Is this issue reproducible with ffmpeg, the application?

I tried several parameter combinations but none of them reached the decode_frame().I even downloaded a standard tiff file and it still fails.

./ffmpeg_g -i file_example_TIFF_1MB.tiff test.tiff
./ffmpeg_g -i pipe:0 test.tiff -y -report < ./file_example_TIFF_1MB.tiff

comment:4 in reply to: ↑ 2 Changed 2 months ago by 1vanChen

Replying to cehoyos:

Is this issue reproducible with ffmpeg, the application?

It can crash after modifying the compilation parameters

root@85943f9aa2c3:/src/ffmpeg# ./ffmpeg_g -i /out/poc1.tiff test.tiff
ffmpeg version git-2020-11-09-d2dcb11 Copyright (c) 2000-2020 the FFmpeg developers
  built with clang version 11.0.0 (https://github.com/llvm/llvm-project.git f7f1abdb8893af4a606ca1a8f5347a426e9c7f9e)
  configuration: --cc=/afl/afl-clang-fast --cxx=/afl/afl-clang-fast++ --ld='/afl/afl-clang-fast++ -stdlib=libc++ -pthread -Wl,--no-as-needed -Wl,-ldl -Wl,-lm -Wno-unused-command-line-argument -O3 -fno-sanitize=vptr -fprofile-instr-generate -fcoverage-mapping -std=c++11' --extra-cflags=-I/src/ffmpeg_deps/include --extra-ldflags=-L/src/ffmpeg_deps/lib --extra-ldflags=-L/afl/ --prefix=/src/ffmpeg_deps --pkg-config-flags=--static --optflags=-O1 --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-nonfree --enable-cross-compile
  libavutil      56. 60.100 / 56. 60.100
  libavcodec     58.112.101 / 58.112.101
  libavformat    58. 64.100 / 58. 64.100
  libavdevice    58. 11.102 / 58. 11.102
  libavfilter     7. 89.100 /  7. 89.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
[tiff @ 0x619000000580] Tiled TIFF is not allowed to strip
Input #0, tiff_pipe, from '/out/poc1.tiff':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: tiff, rgb24, 601x81, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (tiff (native) -> tiff (native))
Press [q] to stop, [?] for help
[tiff @ 0x619000002880] Tiled TIFF is not allowed to strip
AddressSanitizer:DEADLYSIGNAL
=================================================================
==18==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x0000068aef0a bp 0x7fce8a2fe9e0 sp 0x7fce8a2fe9c0 T1)
==18==The signal is caused by a READ memory access.
==18==Hint: this fault was caused by a dereference of a high value address (see register values below).  Dissassemble the provided pc to learn which register was used.
    #0 0x68aef0a in bytestream_get_be32 /src/ffmpeg/libavcodec/bytestream.h:96:1
    #1 0x68aef0a in bytestream2_get_be32u /src/ffmpeg/libavcodec/bytestream.h:96:1
    #2 0x68aef0a in bytestream2_get_be32 /src/ffmpeg/libavcodec/bytestream.h:96:1
    #3 0x68aef0a in ff_tget_long /src/ffmpeg/libavcodec/tiff_common.c:51:44
    #4 0x68b0574 in ff_tget /src/ffmpeg/libavcodec/tiff_common.c:67:29
    #5 0x6848146 in decode_frame /src/ffmpeg/libavcodec/tiff.c:2002:25
    #6 0x60ae782 in frame_worker_thread /src/ffmpeg/libavcodec/pthread_frame.c:201:21
    #7 0x7fce8ff566b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
    #8 0x7fce8ed324dc in clone (/lib/x86_64-linux-gnu/libc.so.6+0x1074dc)

compilation parameters:

# Disable UBSan vptr since several targets built with -fno-rtti.
export CC="/afl/afl-clang-fast"
export CXX="/afl/afl-clang-fast++"
export CFLAGS="-pthread -Wl,--no-as-needed -Wl,-ldl -Wl,-lm -Wno-unused-command-line-argument -O3"
export CXXFLAGS="-stdlib=libc++ -pthread -Wl,--no-as-needed -Wl,-ldl -Wl,-lm -Wno-unused-command-line-argument -O3"
export ARCHITECTURE="x86_64"

export CFLAGS="$CFLAGS -fno-sanitize=vptr"
export CXXFLAGS="$CXXFLAGS -fno-sanitize=vptr"

#add llvm-coverage
export CFLAGS="$CFLAGS -fprofile-instr-generate -fcoverage-mapping"
export CXXFLAGS="$CXXFLAGS -fprofile-instr-generate -fcoverage-mapping"

# Build dependencies.
export FFMPEG_DEPS_PATH=$SRC/ffmpeg_deps
mkdir -p $FFMPEG_DEPS_PATH

export PATH="$FFMPEG_DEPS_PATH/bin:$PATH"
export LD_LIBRARY_PATH="$FFMPEG_DEPS_PATH/lib"


export AFL_LLVM_LAF_SPLIT_SWITCHES=1
export AFL_LLVM_LAF_SPLIT_COMPARES=1


cd $SRC
bzip2 -f -d alsa-lib-*
tar xf alsa-lib-*
cd alsa-lib-*
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/fdk-aac
autoreconf -fiv
CXXFLAGS="$CXXFLAGS -fno-sanitize=shift-base,signed-integer-overflow" \
./configure --prefix="$FFMPEG_DEPS_PATH" --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/libXext
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc)
make install

cd $SRC/libXfixes
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc)
make install

cd $SRC/libva
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/libvdpau
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-shared
make clean
make -j$(nproc) all
make install

cd $SRC/libvpx
LDFLAGS="$CXXFLAGS" ./configure --prefix="$FFMPEG_DEPS_PATH" \
    --disable-examples --disable-unit-tests \
    --size-limit=12288x12288 \
    --extra-cflags="-DVPX_MAX_ALLOCABLE_MEMORY=1073741824"
make clean
make -j$(nproc) all
make install

cd $SRC/ogg
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static --disable-crc
make clean
make -j$(nproc)
make install

cd $SRC/opus
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc) all
make install

cd $SRC/theora
CFLAGS="$CFLAGS -fPIC" LDFLAGS="-L$FFMPEG_DEPS_PATH/lib/" \
    CPPFLAGS="$CXXFLAGS -I$FFMPEG_DEPS_PATH/include/" \
    LD_LIBRARY_PATH="$FFMPEG_DEPS_PATH/lib/" \
    ./autogen.sh
./configure --with-ogg="$FFMPEG_DEPS_PATH" --prefix="$FFMPEG_DEPS_PATH" \
    --enable-static --disable-examples
make clean
make -j$(nproc)
make install

cd $SRC/vorbis
./autogen.sh
./configure --prefix="$FFMPEG_DEPS_PATH" --enable-static
make clean
make -j$(nproc)
make install

# Remove shared libraries to avoid accidental linking against them.
rm $FFMPEG_DEPS_PATH/lib/*.so
rm $FFMPEG_DEPS_PATH/lib/*.so.*

export AFL_USE_ASAN=1
cd $SRC/ffmpeg
PKG_CONFIG_PATH="$FFMPEG_DEPS_PATH/lib/pkgconfig" ./configure \
    --cc=$CC --cxx=$CXX --ld="$CXX $CXXFLAGS -std=c++11" \
    --extra-cflags="-I$FFMPEG_DEPS_PATH/include" \
    --extra-ldflags="-L$FFMPEG_DEPS_PATH/lib" \
    --extra-ldflags="-L/afl/" \
    --prefix="$FFMPEG_DEPS_PATH" \
    --pkg-config-flags="--static" \
    --optflags=-O1 \
    --enable-gpl \
    --enable-libass \
    --enable-libfdk-aac \
    --enable-libfreetype \
    --enable-libopus \
    --enable-libtheora \
    --enable-libvorbis \
    --enable-libvpx \
    --enable-nonfree \
    --enable-cross-compile

make -j$(nproc) install

cp -r $SRC/ffmpeg/  $OUT

comment:5 Changed 2 months ago by cehoyos

  • Keywords crash regression added

comment:6 Changed 3 weeks ago by 1vanChen

  • Resolution set to fixed
  • Status changed from open to closed
Note: See TracTickets for help on using tickets.