xref: /aosp_15_r20/external/libhevc/fuzzer/README.md (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
1*c83a76b0SSuyog Pawar# Fuzzer for libhevc decoder and encoder
2*c83a76b0SSuyog Pawar
3*c83a76b0SSuyog PawarThis describes steps to build hevc_dec_fuzzer and hevc_enc_fuzzer binary.
4*c83a76b0SSuyog Pawar
5*c83a76b0SSuyog Pawar## Linux x86/x64
6*c83a76b0SSuyog Pawar
7*c83a76b0SSuyog Pawar###  Requirements
8*c83a76b0SSuyog Pawar- cmake (3.9.1 or above)
9*c83a76b0SSuyog Pawar- make
10*c83a76b0SSuyog Pawar- clang (6.0 or above)
11*c83a76b0SSuyog Pawar  needs to support -fsanitize=fuzzer, -fsanitize=fuzzer-no-link
12*c83a76b0SSuyog Pawar
13*c83a76b0SSuyog Pawar### Steps to build
14*c83a76b0SSuyog PawarClone libhevc repository
15*c83a76b0SSuyog Pawar```
16*c83a76b0SSuyog Pawar$ git clone https://android.googlesource.com/platform/external/libhevc
17*c83a76b0SSuyog Pawar```
18*c83a76b0SSuyog PawarCreate a directory inside libhevc and change directory
19*c83a76b0SSuyog Pawar```
20*c83a76b0SSuyog Pawar $ cd libhevc
21*c83a76b0SSuyog Pawar $ mkdir build
22*c83a76b0SSuyog Pawar $ cd build
23*c83a76b0SSuyog Pawar```
24*c83a76b0SSuyog PawarBuild fuzzer with required sanitizers (-DSANITIZE=fuzzer-no-link is mandatory
25*c83a76b0SSuyog Pawar  to enable fuzzers)
26*c83a76b0SSuyog Pawar```
27*c83a76b0SSuyog Pawar $ cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
28*c83a76b0SSuyog Pawar   -DCMAKE_BUILD_TYPE=Debug -DSANITIZE=fuzzer-no-link,address
29*c83a76b0SSuyog Pawar $ make
30*c83a76b0SSuyog Pawar ```
31*c83a76b0SSuyog Pawar
32*c83a76b0SSuyog Pawar### Steps to run
33*c83a76b0SSuyog PawarCreate a directory CORPUS_DIR and copy some elementary hevc files
34*c83a76b0SSuyog Pawar(for hevc_dec_fuzzer) or yuv files (for hevc_enc_fuzzer) to that directory
35*c83a76b0SSuyog Pawar
36*c83a76b0SSuyog PawarTo run the fuzzers
37*c83a76b0SSuyog Pawar```
38*c83a76b0SSuyog Pawar$ ./hevc_dec_fuzzer CORPUS_DIR
39*c83a76b0SSuyog Pawar$ ./hevc_enc_fuzzer CORPUS_DIR
40*c83a76b0SSuyog Pawar```
41*c83a76b0SSuyog Pawar
42*c83a76b0SSuyog Pawar## Android
43*c83a76b0SSuyog Pawar
44*c83a76b0SSuyog Pawar### Steps to build
45*c83a76b0SSuyog PawarBuild the fuzzers
46*c83a76b0SSuyog Pawar```
47*c83a76b0SSuyog Pawar  $ mm -j$(nproc) hevc_dec_fuzzer
48*c83a76b0SSuyog Pawar  $ mm -j$(nproc) hevc_enc_fuzzer
49*c83a76b0SSuyog Pawar```
50*c83a76b0SSuyog Pawar
51*c83a76b0SSuyog Pawar### Steps to run
52*c83a76b0SSuyog PawarCreate a directory CORPUS_DIR and copy some elementary hevc files
53*c83a76b0SSuyog Pawar(for hevc_dec_fuzzer) or yuv files (for hevc_enc_fuzzer) to that folder
54*c83a76b0SSuyog PawarPush this directory to device
55*c83a76b0SSuyog Pawar
56*c83a76b0SSuyog PawarTo run hevc_dec_fuzzer on device
57*c83a76b0SSuyog Pawar```
58*c83a76b0SSuyog Pawar  $ adb sync data
59*c83a76b0SSuyog Pawar  $ adb shell /data/fuzz/hevc_dec_fuzzer CORPUS_DIR
60*c83a76b0SSuyog Pawar```
61*c83a76b0SSuyog PawarTo run hevc_enc_fuzzer on device
62*c83a76b0SSuyog Pawar```
63*c83a76b0SSuyog Pawar  $ adb sync data
64*c83a76b0SSuyog Pawar  $ adb shell /data/fuzz/arm64/hevc_enc_fuzzer/hevc_enc_fuzzer CORPUS_DIR
65*c83a76b0SSuyog Pawar```
66*c83a76b0SSuyog Pawar
67*c83a76b0SSuyog PawarTo run hevc_dec_fuzzer on host
68*c83a76b0SSuyog Pawar```
69*c83a76b0SSuyog Pawar  $ $ANDROID_HOST_OUT/fuzz/x86_64/hevc_dec_fuzzer/hevc_dec_fuzzer CORPUS_DIR
70*c83a76b0SSuyog Pawar```
71*c83a76b0SSuyog Pawar
72*c83a76b0SSuyog PawarTo run hevc_enc_fuzzer on host
73*c83a76b0SSuyog Pawar```
74*c83a76b0SSuyog Pawar  $ $ANDROID_HOST_OUT/fuzz/x86_64/hevc_enc_fuzzer/hevc_enc_fuzzer CORPUS_DIR
75*c83a76b0SSuyog Pawar```
76*c83a76b0SSuyog Pawar
77*c83a76b0SSuyog Pawar
78*c83a76b0SSuyog Pawar# Appendix
79*c83a76b0SSuyog Pawar## libhevc encoder fuzzer
80*c83a76b0SSuyog Pawar
81*c83a76b0SSuyog Pawar## Plugin Design Considerations
82*c83a76b0SSuyog PawarThe fuzzer plugin for HEVC is designed based on the understanding of the
83*c83a76b0SSuyog Pawarcodec and tries to achieve the following:
84*c83a76b0SSuyog Pawar
85*c83a76b0SSuyog Pawar##### Maximize code coverage
86*c83a76b0SSuyog PawarThe configuration parameters are not hardcoded, but instead selected based on
87*c83a76b0SSuyog Pawarincoming data. This ensures more code paths are reached by the fuzzer.
88*c83a76b0SSuyog Pawar
89*c83a76b0SSuyog PawarHEVC supports the following parameters:
90*c83a76b0SSuyog Pawar1. Frame Width (parameter name: `i4_width`)
91*c83a76b0SSuyog Pawar2. Frame Height (parameter name: `i4_height`)
92*c83a76b0SSuyog Pawar3. Intra max transform tree depth (parameter name: `i4_max_tr_tree_depth_I`)
93*c83a76b0SSuyog Pawar4. Inter max transform tree depth (parameter name: `i4_max_tr_tree_depth_nI`)
94*c83a76b0SSuyog Pawar5. CU level Qp modulation (parameter name: `i4_cu_level_rc`)
95*c83a76b0SSuyog Pawar6. Rate control mode (parameter name: `i4_rate_control_mode`)
96*c83a76b0SSuyog Pawar7. Frame level Qp (parameter name: `ai4_frame_qp`)
97*c83a76b0SSuyog Pawar8. Encoder quality preset (parameter name: `i4_quality_preset`)
98*c83a76b0SSuyog Pawar9. Target Bitrate (parameter name: `ai4_tgt_bitrate`)
99*c83a76b0SSuyog Pawar10. Enable entropy sync (parameter name: `i4_enable_entropy_sync`)
100*c83a76b0SSuyog Pawar11. Deblocking type (parameter name: `i4_deblocking_type`)
101*c83a76b0SSuyog Pawar12. Default scaling matrices (parameter name: `i4_use_default_sc_mtx`)
102*c83a76b0SSuyog Pawar13. Max temporal layers (parameter name: `i4_max_temporal_layers`)
103*c83a76b0SSuyog Pawar14. Max difference b/w IDR frames (parameter name: `i4_max_closed_gop_period`)
104*c83a76b0SSuyog Pawar15. Min difference b/w IDR frames (parameter name: `i4_min_closed_gop_period`)
105*c83a76b0SSuyog Pawar16. Max difference b/w I frames (parameter name: `i4_max_i_open_gop_period`)
106*c83a76b0SSuyog Pawar17. Max difference b/w CRA frames (parameter name: `i4_max_cra_open_gop_period`)
107*c83a76b0SSuyog Pawar18. Automatic insertion of SPS at each CDR (parameter name: `i4_sps_at_cdr_enable`)
108*c83a76b0SSuyog Pawar19. Enable VUI output (parameter name: `i4_vui_enable`)
109*c83a76b0SSuyog Pawar20. Enable SEI messages (parameter name: `i4_sei_enable_flag`)
110*c83a76b0SSuyog Pawar21. Architecture type (parameter name: `e_arch_type`)
111*c83a76b0SSuyog Pawar22. Enable force IDR frame test(parameter name: `mIsForceIdrEnabled`)
112*c83a76b0SSuyog Pawar23. Enable dynamic bitrate test (parameter name: `mIsDynamicBitrateChangeEnabled`)
113*c83a76b0SSuyog Pawar24. Force IDR frame number (parameter name: `mForceIdrInterval`)
114*c83a76b0SSuyog Pawar25. Frame number for dynamic bitrate  (parameter name: `mDynamicBitrateInterval`)
115*c83a76b0SSuyog Pawar
116*c83a76b0SSuyog Pawar| Parameter| Valid Values| Configured Value|
117*c83a76b0SSuyog Pawar|------------- |-------------| ----- |
118*c83a76b0SSuyog Pawar| `i4_width` | In the range `0 to 10239` | All the bits of 1st and 2nd byte of data |
119*c83a76b0SSuyog Pawar| `i4_height` | In the range `0 to 10239` | All the bits of 3rd and 4th byte of data |
120*c83a76b0SSuyog Pawar| `i4_max_tr_tree_depth_I` | 0. `1` 1. `2` 2. `3` | All the bits of 5th byte of data |
121*c83a76b0SSuyog Pawar| `i4_max_tr_tree_depth_nI` | 0. `1` 1. `2` 2. `3` 3. `4` | bit 0 and 1 of 6th byte of data |
122*c83a76b0SSuyog Pawar| `i4_cu_level_rc` | 0. `0` 1. `1` | bit 0 of 7th byte of data |
123*c83a76b0SSuyog Pawar| `i4_rate_control_mode` | 0. `VBR` 1. `CQP` 2. `CBR` | All the bits of 8th byte of data modulus 3 |
124*c83a76b0SSuyog Pawar| `ai4_frame_qp` | In the range `1 to 51` | All the bits of 9th byte of data |
125*c83a76b0SSuyog Pawar| `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 |
126*c83a76b0SSuyog Pawar| `ai4_tgt_bitrate` | In the range `0 to 500000000` | All the bits of 11th and 12th byte of data |
127*c83a76b0SSuyog Pawar| `i4_enable_entropy_sync` | 0. `0` 1. `1` | bit 0 of 13th byte of data |
128*c83a76b0SSuyog Pawar| `i4_deblocking_type` | 0. `0` 1. `1` | bit 0 of 14th byte of data |
129*c83a76b0SSuyog Pawar| `i4_use_default_sc_mtx` | 0. `0` 1. `1` | bit 0 of 15th byte of data |
130*c83a76b0SSuyog Pawar| `i4_max_temporal_layers` | 0. `0` 1. `1` 2. `2` 3. `3` | bit 0 and 1 of 16th byte of data |
131*c83a76b0SSuyog Pawar| `i4_max_closed_gop_period` | In the range `0 to 255` | All the bits of 17th byte of data |
132*c83a76b0SSuyog Pawar| `i4_min_closed_gop_period` | In the range `0 to 255` | All the bits of 18th byte of data |
133*c83a76b0SSuyog Pawar| `i4_max_i_open_gop_period` | In the range `0 to 255` | All the bits of 19th byte of data |
134*c83a76b0SSuyog Pawar| `i4_max_cra_open_gop_period` | In the range `0 to 255` | All the bits of 20th byte of data |
135*c83a76b0SSuyog Pawar| `i4_sps_at_cdr_enable` | 0. `0` 1. `1` | bit 0 of 21st byte of data |
136*c83a76b0SSuyog Pawar| `i4_vui_enable` | 0. `0` 1. `1` | bit 0 of 22nd byte of data |
137*c83a76b0SSuyog Pawar| `i4_sei_enable_flag` | 0. `0` 1. `1` | bit 0 of 23th byte of data |
138*c83a76b0SSuyog Pawar| `e_arch_type` | 0. `ARCH_ARM_NONEON` 1. `ARCH_NA` | bit 0 and 1 of 24th byte of data |
139*c83a76b0SSuyog Pawar| `mIsForceIdrEnabled` | 0. `0` 1. `1` | bit 0 of 25th byte of data |
140*c83a76b0SSuyog Pawar| `mIsDynamicBitrateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 	 byte of data |
141*c83a76b0SSuyog Pawar| `mForceIdrInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 27th byte of data |
142*c83a76b0SSuyog Pawar| `mDynamicBitrateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 28th byte of data |
143*c83a76b0SSuyog Pawar
144*c83a76b0SSuyog PawarThis also ensures that the plugin is always deterministic for any given input.
145*c83a76b0SSuyog Pawar
146*c83a76b0SSuyog Pawar##### Maximize utilization of input data
147*c83a76b0SSuyog PawarThe plugin feeds the entire input data to the codec using a loop.
148*c83a76b0SSuyog PawarIf the encode operation was successful, the input is advanced by the frame size.
149*c83a76b0SSuyog PawarIf the encode operation was un-successful, the input is still advanced by frame size so
150*c83a76b0SSuyog Pawarthat the fuzzer can proceed to feed the next frame.
151*c83a76b0SSuyog Pawar
152*c83a76b0SSuyog PawarThis ensures that the plugin tolerates any kind of input (empty, huge,
153*c83a76b0SSuyog Pawarmalformed, etc) and doesnt `exit()` on any input and thereby increasing the
154*c83a76b0SSuyog Pawarchance of identifying vulnerabilities.
155*c83a76b0SSuyog Pawar
156*c83a76b0SSuyog Pawar
157*c83a76b0SSuyog Pawar## References:
158*c83a76b0SSuyog Pawar * http://llvm.org/docs/LibFuzzer.html
159*c83a76b0SSuyog Pawar * https://github.com/google/oss-fuzz
160