2 * This file is part of FFmpeg.
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 /* Targeted fuzzer that targets specific codecs depending on two
23 * Get the very fresh clang, e.g. see http://libfuzzer.info#versions
24 * Get and build libFuzzer:
25 svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
27 * build ffmpeg for fuzzing:
28 FLAGS="-fsanitize=address -fsanitize-coverage=trace-pc-guard,trace-cmp -g" CC="clang $FLAGS" CXX="clang++ $FLAGS" ./configure --disable-x86asm
30 * build the fuzz target.
31 Choose the value of FFMPEG_CODEC (e.g. AV_CODEC_ID_DVD_SUBTITLE) and
32 choose one of FUZZ_FFMPEG_VIDEO, FUZZ_FFMPEG_AUDIO, FUZZ_FFMPEG_SUBTITLE.
33 clang -fsanitize=address -fsanitize-coverage=trace-pc-guard,trace-cmp tools/target_dec_fuzzer.c -o target_dec_fuzzer -I. -DFFMPEG_CODEC=AV_CODEC_ID_MPEG1VIDEO -DFUZZ_FFMPEG_VIDEO ../../libfuzzer/libFuzzer.a -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -ldl -lxcb -lxcb-shm -lxcb -lxcb-xfixes -lxcb -lxcb-shape -lxcb -lX11 -lasound -lm -lbz2 -lz -pthread
34 * create a corpus directory and put some samples there (empty dir is ok too):
35 mkdir CORPUS && cp some-files CORPUS
38 ./target_dec_fuzzer -max_len=100000 CORPUS
42 http://tutorial.libfuzzer.info
43 https://github.com/google/oss-fuzz
44 http://lcamtuf.coredump.cx/afl/
45 https://security.googleblog.com/2016/08/guided-in-process-fuzzing-of-chrome.html
49 #include "libavutil/avassert.h"
50 #include "libavutil/imgutils.h"
51 #include "libavutil/intreadwrite.h"
53 #include "libavcodec/avcodec.h"
54 #include "libavcodec/bytestream.h"
55 #include "libavformat/avformat.h"
57 //For FF_SANE_NB_CHANNELS, so we dont waste energy testing things that will get instantly rejected
58 #include "libavcodec/internal.h"
60 int LLVMFuzzerTestOneInput(const uint8_t *data
, size_t size
);
62 extern AVCodec
* codec_list
[];
64 static void error(const char *err
)
66 fprintf(stderr
, "%s", err
);
70 static AVCodec
*c
= NULL
;
71 static AVCodec
*AVCodecInitialize(enum AVCodecID codec_id
)
75 res
= avcodec_find_decoder(codec_id
);
77 error("Failed to find decoder");
81 static int subtitle_handler(AVCodecContext
*avctx
, void *frame
,
82 int *got_sub_ptr
, AVPacket
*avpkt
)
85 int ret
= avcodec_decode_subtitle2(avctx
, &sub
, got_sub_ptr
, avpkt
);
86 if (ret
>= 0 && *got_sub_ptr
)
87 avsubtitle_free(&sub
);
91 // Ensure we don't loop forever
92 const uint32_t maxiteration
= 8096;
93 const uint64_t maxpixels_per_frame
= 4096 * 4096;
96 uint64_t maxsamples_per_frame
= 256*1024*32;
99 static const uint64_t FUZZ_TAG
= 0x4741542D5A5A5546ULL
;
101 int LLVMFuzzerTestOneInput(const uint8_t *data
, size_t size
) {
102 const uint64_t fuzz_tag
= FUZZ_TAG
;
103 const uint8_t *last
= data
;
104 const uint8_t *end
= data
+ size
;
106 uint64_t ec_pixels
= 0;
107 uint64_t nb_samples
= 0;
108 int (*decode_handler
)(AVCodecContext
*avctx
, AVFrame
*picture
,
109 int *got_picture_ptr
,
110 const AVPacket
*avpkt
) = NULL
;
111 AVCodecParserContext
*parser
= NULL
;
112 uint64_t keyframes
= 0;
113 AVDictionary
*opts
= NULL
;
116 #ifdef FFMPEG_DECODER
117 #define DECODER_SYMBOL0(CODEC) ff_##CODEC##_decoder
118 #define DECODER_SYMBOL(CODEC) DECODER_SYMBOL0(CODEC)
119 extern AVCodec
DECODER_SYMBOL(FFMPEG_DECODER
);
120 codec_list
[0] = &DECODER_SYMBOL(FFMPEG_DECODER
);
121 avcodec_register(&DECODER_SYMBOL(FFMPEG_DECODER
));
123 #if FFMPEG_DECODER == tiff || FFMPEG_DECODER == tdsc
124 extern AVCodec
DECODER_SYMBOL(mjpeg
);
125 codec_list
[1] = &DECODER_SYMBOL(mjpeg
);
126 avcodec_register(&DECODER_SYMBOL(mjpeg
));
129 c
= &DECODER_SYMBOL(FFMPEG_DECODER
);
131 avcodec_register_all();
132 c
= AVCodecInitialize(FFMPEG_CODEC
); // Done once.
134 av_log_set_level(AV_LOG_PANIC
);
138 case AVMEDIA_TYPE_AUDIO
: decode_handler
= avcodec_decode_audio4
; break;
139 case AVMEDIA_TYPE_VIDEO
: decode_handler
= avcodec_decode_video2
; break;
140 case AVMEDIA_TYPE_SUBTITLE
: decode_handler
= subtitle_handler
; break;
143 case AV_CODEC_ID_APE
: maxsamples_per_frame
/= 256; break;
145 maxpixels
= maxpixels_per_frame
* maxiteration
;
146 maxsamples
= maxsamples_per_frame
* maxiteration
;
148 case AV_CODEC_ID_BINKVIDEO
: maxpixels
/= 32; break;
149 case AV_CODEC_ID_CFHD
: maxpixels
/= 128; break;
150 case AV_CODEC_ID_DIRAC
: maxpixels
/= 8192; break;
151 case AV_CODEC_ID_DST
: maxsamples
/= 8192; break;
152 case AV_CODEC_ID_DXV
: maxpixels
/= 32; break;
153 case AV_CODEC_ID_FFWAVESYNTH
: maxsamples
/= 16384; break;
154 case AV_CODEC_ID_G2M
: maxpixels
/= 64; break;
155 case AV_CODEC_ID_GDV
: maxpixels
/= 512; break;
156 case AV_CODEC_ID_GIF
: maxpixels
/= 16; break;
157 case AV_CODEC_ID_H264
: maxpixels
/= 256; break;
158 case AV_CODEC_ID_HAP
: maxpixels
/= 128; break;
159 case AV_CODEC_ID_HEVC
: maxpixels
/= 16384; break;
160 case AV_CODEC_ID_HNM4_VIDEO
: maxpixels
/= 128; break;
161 case AV_CODEC_ID_IFF_ILBM
: maxpixels
/= 128; break;
162 case AV_CODEC_ID_INDEO4
: maxpixels
/= 128; break;
163 case AV_CODEC_ID_LSCR
: maxpixels
/= 16; break;
164 case AV_CODEC_ID_MMVIDEO
: maxpixels
/= 256; break;
165 case AV_CODEC_ID_MOTIONPIXELS
:maxpixels
/= 256; break;
166 case AV_CODEC_ID_MP4ALS
: maxsamples
/= 65536; break;
167 case AV_CODEC_ID_MSRLE
: maxpixels
/= 16; break;
168 case AV_CODEC_ID_MSS2
: maxpixels
/= 16384; break;
169 case AV_CODEC_ID_MSZH
: maxpixels
/= 128; break;
170 case AV_CODEC_ID_PNG
: maxpixels
/= 128; break;
171 case AV_CODEC_ID_APNG
: maxpixels
/= 128; break;
172 case AV_CODEC_ID_QTRLE
: maxpixels
/= 16; break;
173 case AV_CODEC_ID_RASC
: maxpixels
/= 16; break;
174 case AV_CODEC_ID_RTV1
: maxpixels
/= 16; break;
175 case AV_CODEC_ID_SANM
: maxpixels
/= 16; break;
176 case AV_CODEC_ID_SCPR
: maxpixels
/= 32; break;
177 case AV_CODEC_ID_SCREENPRESSO
:maxpixels
/= 64; break;
178 case AV_CODEC_ID_SMACKVIDEO
: maxpixels
/= 64; break;
179 case AV_CODEC_ID_SNOW
: maxpixels
/= 128; break;
180 case AV_CODEC_ID_TGV
: maxpixels
/= 32; break;
181 case AV_CODEC_ID_TRUEMOTION2
: maxpixels
/= 1024; break;
182 case AV_CODEC_ID_VP7
: maxpixels
/= 256; break;
183 case AV_CODEC_ID_VP9
: maxpixels
/= 4096; break;
184 case AV_CODEC_ID_ZEROCODEC
: maxpixels
/= 128; break;
188 AVCodecContext
* ctx
= avcodec_alloc_context3(c
);
189 AVCodecContext
* parser_avctx
= avcodec_alloc_context3(NULL
);
190 if (!ctx
|| !parser_avctx
)
191 error("Failed memory allocation");
193 if (ctx
->max_pixels
== 0 || ctx
->max_pixels
> maxpixels_per_frame
)
194 ctx
->max_pixels
= maxpixels_per_frame
; //To reduce false positive OOM and hangs
195 ctx
->refcounted_frames
= 1; //To reduce false positive timeouts and focus testing on the refcounted API
197 ctx
->max_samples
= maxsamples_per_frame
;
204 bytestream2_init(&gbc
, data
+ size
, 1024);
205 ctx
->width
= bytestream2_get_le32(&gbc
);
206 ctx
->height
= bytestream2_get_le32(&gbc
);
207 ctx
->bit_rate
= bytestream2_get_le64(&gbc
);
208 ctx
->bits_per_coded_sample
= bytestream2_get_le32(&gbc
);
209 // Try to initialize a parser for this codec, note, this may fail which just means we test without one
210 flags
= bytestream2_get_byte(&gbc
);
212 parser
= av_parser_init(c
->id
);
214 ctx
->strict_std_compliance
= FF_COMPLIANCE_EXPERIMENTAL
;
216 ctx
->err_recognition
= AV_EF_AGGRESSIVE
| AV_EF_COMPLIANT
| AV_EF_CAREFUL
;
218 ctx
->err_recognition
|= AV_EF_EXPLODE
;
220 if ((flags
& 0x10) && c
->id
!= AV_CODEC_ID_H264
)
221 ctx
->flags2
|= AV_CODEC_FLAG2_FAST
;
224 av_force_cpu_flags(0);
226 extradata_size
= bytestream2_get_le32(&gbc
);
228 ctx
->sample_rate
= bytestream2_get_le32(&gbc
) & 0x7FFFFFFF;
229 ctx
->channels
= (unsigned)bytestream2_get_le32(&gbc
) % FF_SANE_NB_CHANNELS
;
230 ctx
->block_align
= bytestream2_get_le32(&gbc
) & 0x7FFFFFFF;
231 ctx
->codec_tag
= bytestream2_get_le32(&gbc
);
234 for (n
= 0; c
->codec_tags
[n
] != FF_CODEC_TAGS_END
; n
++);
235 ctx
->codec_tag
= c
->codec_tags
[ctx
->codec_tag
% n
];
237 keyframes
= bytestream2_get_le64(&gbc
);
238 ctx
->request_channel_layout
= bytestream2_get_le64(&gbc
);
240 ctx
->idct_algo
= bytestream2_get_byte(&gbc
) % 25;
243 switch (ctx
->codec_id
) {
244 case AV_CODEC_ID_AC3
:
245 case AV_CODEC_ID_EAC3
:
246 av_dict_set_int(&opts
, "cons_noisegen", bytestream2_get_byte(&gbc
) & 1, 0);
247 av_dict_set_int(&opts
, "heavy_compr", bytestream2_get_byte(&gbc
) & 1, 0);
248 av_dict_set_int(&opts
, "target_level", (int)(bytestream2_get_byte(&gbc
) % 32) - 31, 0);
249 av_dict_set_int(&opts
, "dmix_mode", (int)(bytestream2_get_byte(&gbc
) % 4) - 1, 0);
255 if (extradata_size
< size
) {
256 ctx
->extradata
= av_mallocz(extradata_size
+ AV_INPUT_BUFFER_PADDING_SIZE
);
257 if (ctx
->extradata
) {
258 ctx
->extradata_size
= extradata_size
;
259 size
-= ctx
->extradata_size
;
260 memcpy(ctx
->extradata
, data
+ size
, ctx
->extradata_size
);
263 if (av_image_check_size(ctx
->width
, ctx
->height
, 0, ctx
))
264 ctx
->width
= ctx
->height
= 0;
267 int res
= avcodec_open2(ctx
, c
, &opts
);
269 avcodec_free_context(&ctx
);
270 av_free(parser_avctx
);
271 av_parser_close(parser
);
273 return 0; // Failure of avcodec_open2() does not imply that a issue was found
275 parser_avctx
->codec_id
= ctx
->codec_id
;
278 AVFrame
*frame
= av_frame_alloc();
280 error("Failed memory allocation");
282 // Read very simple container
283 AVPacket avpkt
, parsepkt
;
284 av_init_packet(&avpkt
);
285 av_init_packet(&parsepkt
);
286 while (data
< end
&& it
< maxiteration
) {
287 // Search for the TAG
288 while (data
+ sizeof(fuzz_tag
) < end
) {
289 if (data
[0] == (fuzz_tag
& 0xFF) && AV_RN64(data
) == fuzz_tag
)
293 if (data
+ sizeof(fuzz_tag
) > end
)
296 res
= av_new_packet(&parsepkt
, data
- last
);
298 error("Failed memory allocation");
299 memcpy(parsepkt
.data
, last
, data
- last
);
300 parsepkt
.flags
= (keyframes
& 1) * AV_PKT_FLAG_DISCARD
+ (!!(keyframes
& 2)) * AV_PKT_FLAG_KEY
;
301 keyframes
= (keyframes
>> 2) + (keyframes
<<62);
302 data
+= sizeof(fuzz_tag
);
305 while (parsepkt
.size
> 0) {
308 av_init_packet(&avpkt
);
309 int ret
= av_parser_parse2(parser
, parser_avctx
, &avpkt
.data
, &avpkt
.size
,
310 parsepkt
.data
, parsepkt
.size
,
311 parsepkt
.pts
, parsepkt
.dts
, parsepkt
.pos
);
312 if (avpkt
.data
== parsepkt
.data
) {
313 avpkt
.buf
= av_buffer_ref(parsepkt
.buf
);
315 error("Failed memory allocation");
317 if (av_packet_make_refcounted(&avpkt
) < 0)
318 error("Failed memory allocation");
320 parsepkt
.data
+= ret
;
321 parsepkt
.size
-= ret
;
323 avpkt
.pts
= parser
->pts
;
324 avpkt
.dts
= parser
->dts
;
325 avpkt
.pos
= parser
->pos
;
326 if ( parser
->key_frame
== 1 ||
327 (parser
->key_frame
== -1 && parser
->pict_type
== AV_PICTURE_TYPE_I
))
328 avpkt
.flags
|= AV_PKT_FLAG_KEY
;
329 avpkt
.flags
|= parsepkt
.flags
& AV_PKT_FLAG_DISCARD
;
331 av_packet_move_ref(&avpkt
, &parsepkt
);
334 // Iterate through all data
335 while (avpkt
.size
> 0 && it
++ < maxiteration
) {
336 av_frame_unref(frame
);
337 int ret
= decode_handler(ctx
, frame
, &got_frame
, &avpkt
);
339 ec_pixels
+= (ctx
->width
+ 32LL) * (ctx
->height
+ 32LL);
340 if (it
> 20 || ec_pixels
> 4 * ctx
->max_pixels
)
341 ctx
->error_concealment
= 0;
342 if (ec_pixels
> maxpixels
)
343 goto maximums_reached
;
345 nb_samples
+= frame
->nb_samples
;
346 if (nb_samples
> maxsamples
)
347 goto maximums_reached
;
349 if (ret
<= 0 || ret
> avpkt
.size
)
351 if (ctx
->codec_type
!= AVMEDIA_TYPE_AUDIO
)
356 av_packet_unref(&avpkt
);
358 av_packet_unref(&parsepkt
);
362 av_packet_unref(&avpkt
);
366 av_frame_unref(frame
);
367 decode_handler(ctx
, frame
, &got_frame
, &avpkt
);
368 } while (got_frame
== 1 && it
++ < maxiteration
);
370 fprintf(stderr
, "pixels decoded: %"PRId64
", samples decoded: %"PRId64
", iterations: %d\n", ec_pixels
, nb_samples
, it
);
372 av_frame_free(&frame
);
373 avcodec_free_context(&ctx
);
374 avcodec_free_context(&parser_avctx
);
375 av_parser_close(parser
);
376 av_packet_unref(&parsepkt
);