• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Fuzzer for libhevc decoder
2
3This describes steps to build hevc_dec_fuzzer binary.
4
5## Linux x86/x64
6
7###  Requirements
8- cmake (3.5 or above)
9- make
10- clang (6.0 or above)
11  needs to support -fsanitize=fuzzer, -fsanitize=fuzzer-no-link
12
13### Steps to build
14Clone libhevc repository
15```
16$ git clone https://android.googlesource.com/platform/external/libhevc
17```
18Create a directory inside libhevc and change directory
19```
20 $ cd libhevc
21 $ mkdir build
22 $ cd build
23```
24Build libhevc using cmake
25```
26 $ CC=clang CXX=clang++ cmake ../ \
27   -DSANITIZE=fuzzer-no-link,address,signed-integer-overflow
28 $ make
29 ```
30Build the fuzzer
31```
32 $ clang++ -std=c++11 -fsanitize=fuzzer,address -I.  -I../  -I../common \
33   -I../decoder -Wl,--start-group ../fuzzer/hevc_dec_fuzzer.cpp \
34   -o ./hevc_dec_fuzzer ./libhevcdec.a -Wl,--end-group
35```
36
37### Steps to run
38Create a directory CORPUS_DIR and copy some elementary hevc files to that folder
39To run the fuzzer
40```
41$ ./hevc_dec_fuzzer CORPUS_DIR
42```
43
44## Android
45
46### Steps to build
47Build the fuzzer
48```
49  $ SANITIZE_TARGET=address SANITIZE_HOST=address mmma -j$(nproc) \
50    external/libhevc/fuzzer
51```
52
53### Steps to run
54Create a directory CORPUS_DIR and copy some elementary hevc files to that folder
55Push this directory to device.
56
57To run on device
58```
59  $ adb sync data
60  $ adb shell /data/fuzz/hevc_dec_fuzzer CORPUS_DIR
61```
62To run on host
63```
64  $ $ANDROID_HOST_OUT/fuzz/hevc_dec_fuzzer CORPUS_DIR
65```
66
67
68# Fuzzer for libhevc encoder
69
70## Plugin Design Considerations
71The fuzzer plugin for HEVC is designed based on the understanding of the
72codec and tries to achieve the following:
73
74##### Maximize code coverage
75The configuration parameters are not hardcoded, but instead selected based on
76incoming data. This ensures more code paths are reached by the fuzzer.
77
78HEVC supports the following parameters:
791. Frame Width (parameter name: `i4_width`)
802. Frame Height (parameter name: `i4_height`)
813. Intra max transform tree depth (parameter name: `i4_max_tr_tree_depth_I`)
824. Inter max transform tree depth (parameter name: `i4_max_tr_tree_depth_nI`)
835. CU level Qp modulation (parameter name: `i4_cu_level_rc`)
846. Rate control mode (parameter name: `i4_rate_control_mode`)
857. Frame level Qp (parameter name: `ai4_frame_qp`)
868. Encoder quality preset (parameter name: `i4_quality_preset`)
879. Target Bitrate (parameter name: `ai4_tgt_bitrate`)
8810. Enable entropy sync (parameter name: `i4_enable_entropy_sync`)
8911. Deblocking type (parameter name: `i4_deblocking_type`)
9012. Default scaling matrices (parameter name: `i4_use_default_sc_mtx`)
9113. Max temporal layers (parameter name: `i4_max_temporal_layers`)
9214. Max difference b/w IDR frames (parameter name: `i4_max_closed_gop_period`)
9315. Min difference b/w IDR frames (parameter name: `i4_min_closed_gop_period`)
9416. Max difference b/w I frames (parameter name: `i4_max_i_open_gop_period`)
9517. Max difference b/w CRA frames (parameter name: `i4_max_cra_open_gop_period`)
9618. Automatic insertion of SPS at each CDR (parameter name: `i4_sps_at_cdr_enable`)
9719. Enable VUI output (parameter name: `i4_vui_enable`)
9820. Enable SEI messages (parameter name: `i4_sei_enable_flag`)
9921. Architecture type (parameter name: `e_arch_type`)
10022. Enable force IDR frame test(parameter name: `mIsForceIdrEnabled`)
10123. Enable dynamic bitrate test (parameter name: `mIsDynamicBitrateChangeEnabled`)
10224. Force IDR frame number (parameter name: `mForceIdrInterval`)
10325. Frame number for dynamic bitrate  (parameter name: `mDynamicBitrateInterval`)
104
105| Parameter| Valid Values| Configured Value|
106|------------- |-------------| ----- |
107| `i4_width` | In the range `0 to 10239` | All the bits of 1st and 2nd byte of data |
108| `i4_height` | In the range `0 to 10239` | All the bits of 3rd and 4th byte of data |
109| `i4_max_tr_tree_depth_I` | 0. `1` 1. `2` 2. `3` | All the bits of 5th byte of data |
110| `i4_max_tr_tree_depth_nI` | 0. `1` 1. `2` 2. `3` 3. `4` | bit 0 and 1 of 6th byte of data |
111| `i4_cu_level_rc` | 0. `0` 1. `1` | bit 0 of 7th byte of data |
112| `i4_rate_control_mode` | 0. `VBR` 1. `CQP` 2. `CBR` | All the bits of 8th byte of data modulus 3 |
113| `ai4_frame_qp` | In the range `1 to 51` | All the bits of 9th byte of data |
114| `i4_quality_preset` | 0. `IHEVCE_QUALITY_P0` 1. `IHEVCE_QUALITY_P2` 2. `IHEVCE_QUALITY_P3` 3. `IHEVCE_QUALITY_P4 4. `IHEVCE_QUALITY_P5` 5. `IHEVCE_QUALITY_P6` 6. `IHEVCE_QUALITY_P7` | All the bits of 10th byte of data modulus 7 |
115| `ai4_tgt_bitrate` | In the range `0 to 500000000` | All the bits of 11th and 12th byte of data |
116| `i4_enable_entropy_sync` | 0. `0` 1. `1` | bit 0 of 13th byte of data |
117| `i4_deblocking_type` | 0. `0` 1. `1` | bit 0 of 14th byte of data |
118| `i4_use_default_sc_mtx` | 0. `0` 1. `1` | bit 0 of 15th byte of data |
119| `i4_max_temporal_layers` | 0. `0` 1. `1` 2. `2` 3. `3` | bit 0 and 1 of 16th byte of data |
120| `i4_max_closed_gop_period` | In the range `0 to 255` | All the bits of 17th byte of data |
121| `i4_min_closed_gop_period` | In the range `0 to 255` | All the bits of 18th byte of data |
122| `i4_max_i_open_gop_period` | In the range `0 to 255` | All the bits of 19th byte of data |
123| `i4_max_cra_open_gop_period` | In the range `0 to 255` | All the bits of 20th byte of data |
124| `i4_sps_at_cdr_enable` | 0. `0` 1. `1` | bit 0 of 21st byte of data |
125| `i4_vui_enable` | 0. `0` 1. `1` | bit 0 of 22nd byte of data |
126| `i4_sei_enable_flag` | 0. `0` 1. `1` | bit 0 of 23th byte of data |
127| `e_arch_type` | 0. `ARCH_ARM_NONEON` 1. `ARCH_NA` | bit 0 and 1 of 24th byte of data |
128| `mIsForceIdrEnabled` | 0. `0` 1. `1` | bit 0 of 25th byte of data |
129| `mIsDynamicBitrateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 	 byte of data |
130| `mForceIdrInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 27th byte of data |
131| `mDynamicBitrateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 28th byte of data |
132
133This also ensures that the plugin is always deterministic for any given input.
134
135##### Maximize utilization of input data
136The plugin feeds the entire input data to the codec using a loop.
137If the encode operation was successful, the input is advanced by the frame size.
138If the encode operation was un-successful, the input is still advanced by frame size so
139that the fuzzer can proceed to feed the next frame.
140
141This ensures that the plugin tolerates any kind of input (empty, huge,
142malformed, etc) and doesnt `exit()` on any input and thereby increasing the
143chance of identifying vulnerabilities.
144
145## Build
146
147This describes steps to build hevc_enc_fuzzer binary.
148
149### Android
150
151#### Steps to build
152Build the fuzzer
153```
154  $ mm -j$(nproc) hevc_enc_fuzzer
155```
156
157#### Steps to run
158Create a directory CORPUS_DIR and copy some yuv files to that folder
159Push this directory to device.
160
161To run on device
162```
163  $ adb sync data
164  $ adb shell /data/fuzz/arm64/hevc_enc_fuzzer/hevc_enc_fuzzer CORPUS_DIR
165```
166To run on host
167```
168  $ $ANDROID_HOST_OUT/fuzz/x86_64/hevc_enc_fuzzer/hevc_enc_fuzzer CORPUS_DIR
169```
170
171## References:
172 * http://llvm.org/docs/LibFuzzer.html
173 * https://github.com/google/oss-fuzz
174