xref: /aosp_15_r20/external/libopus/fuzzer/README.md (revision a58d3d2adb790c104798cd88c8a3aff4fa8b82cc)
1*a58d3d2aSXin Li# Fuzzer for libopus decoder
2*a58d3d2aSXin Li
3*a58d3d2aSXin Li## Plugin Design Considerations
4*a58d3d2aSXin LiThe fuzzer plugin for opus decoder is designed based on the understanding of the
5*a58d3d2aSXin Licodec and tries to achieve the following:
6*a58d3d2aSXin Li
7*a58d3d2aSXin Li##### Maximize code coverage
8*a58d3d2aSXin Li
9*a58d3d2aSXin LiThis fuzzer provides support for both single stream and multi stream inputs,
10*a58d3d2aSXin Lithus enabling fuzzing for API's provided for single stream as well as multi
11*a58d3d2aSXin Listream.
12*a58d3d2aSXin Li
13*a58d3d2aSXin LiFollowing arguments are passed to OPUS_DEC_CREATE_API:
14*a58d3d2aSXin Li
15*a58d3d2aSXin Li1. Sampling frequency (parameter name: `Fs`)
16*a58d3d2aSXin Li2. Number of channels (parameter name: `channels`)
17*a58d3d2aSXin Li
18*a58d3d2aSXin Li| Parameter| Valid Values| Configured Value|
19*a58d3d2aSXin Li|------------- |-------------| ----- |
20*a58d3d2aSXin Li| `Fs` | `8000 ` `12000 ` `16000 ` `24000 ` `48000 ` | Derived from Byte-9 of input stream|
21*a58d3d2aSXin Li| `channels`   | `1 ` `2 ` | Derived from Byte-9 of input stream |
22*a58d3d2aSXin Li
23*a58d3d2aSXin Li##### Maximize utilization of input data
24*a58d3d2aSXin LiThe plugin feeds the entire input data to the codec. Frame sizes are determined only
25*a58d3d2aSXin Liafter the call to extractor, so in absence of call to extractor,
26*a58d3d2aSXin Liwe feed the entire data to the decoder.
27*a58d3d2aSXin LiThis ensures that the plugin tolerates any kind of input (empty, huge,
28*a58d3d2aSXin Limalformed, etc) and doesnt `exit()` on any input and thereby increasing the
29*a58d3d2aSXin Lichance of identifying vulnerabilities.
30*a58d3d2aSXin Li
31*a58d3d2aSXin Li## Build
32*a58d3d2aSXin Li
33*a58d3d2aSXin LiThis describes steps to build opus_dec_fuzzer and opus_multistream_dec_fuzzer binary.
34*a58d3d2aSXin Li
35*a58d3d2aSXin Li## Android
36*a58d3d2aSXin Li
37*a58d3d2aSXin Li### Steps to build
38*a58d3d2aSXin LiBuild the fuzzer
39*a58d3d2aSXin Li```
40*a58d3d2aSXin Li  $ mm -j$(nproc) opus_dec_fuzzer
41*a58d3d2aSXin Li  $ mm -j$(nproc) opus_multistream_dec_fuzzer
42*a58d3d2aSXin Li```
43*a58d3d2aSXin Li
44*a58d3d2aSXin Li### Steps to run
45*a58d3d2aSXin LiCreate a directory CORPUS_DIR and copy some opus files to that folder.
46*a58d3d2aSXin LiPush this directory to device.
47*a58d3d2aSXin Li
48*a58d3d2aSXin LiTo run on device
49*a58d3d2aSXin Li```
50*a58d3d2aSXin Li  $ adb sync data
51*a58d3d2aSXin Li  $ adb shell /data/fuzz/arm64/opus_dec_fuzzer/opus_dec_fuzzer CORPUS_DIR
52*a58d3d2aSXin Li  $ adb shell /data/fuzz/arm64/opus_multistream_dec_fuzzer/opus_multistream_dec_fuzzer CORPUS_DIR
53*a58d3d2aSXin Li```
54*a58d3d2aSXin LiTo run on host
55*a58d3d2aSXin Li```
56*a58d3d2aSXin Li  $ $ANDROID_HOST_OUT/fuzz/x86_64/opus_dec_fuzzer/opus_dec_fuzzer CORPUS_DIR
57*a58d3d2aSXin Li  $ $ANDROID_HOST_OUT/fuzz/x86_64/opus_multistream_dec_fuzzer/opus_multistream_dec_fuzzer CORPUS_DIR
58*a58d3d2aSXin Li```
59*a58d3d2aSXin Li
60*a58d3d2aSXin Li# Fuzzer for libopus encoder
61*a58d3d2aSXin Li
62*a58d3d2aSXin Li## Plugin Design Considerations
63*a58d3d2aSXin LiThe fuzzer plugin for opus encoder is designed based on the understanding of the
64*a58d3d2aSXin Licodec and tries to achieve the following:
65*a58d3d2aSXin Li
66*a58d3d2aSXin Li##### Maximize code coverage
67*a58d3d2aSXin Li
68*a58d3d2aSXin LiThis fuzzer provides support for both single stream and multi stream inputs,
69*a58d3d2aSXin Lithus enabling fuzzing for API's provided for single stream as well as multi
70*a58d3d2aSXin Listream.
71*a58d3d2aSXin LiFollowing arguments are passed to OPUS_ENC_CREATE_API:
72*a58d3d2aSXin Li
73*a58d3d2aSXin Li1. Sampling rate (parameter name: `sampleRate`)
74*a58d3d2aSXin Li2. Number of channels (parameter name: `channels`)
75*a58d3d2aSXin Li
76*a58d3d2aSXin Li| Parameter| Valid Values| Configured Value|
77*a58d3d2aSXin Li|------------- |-------------| ----- |
78*a58d3d2aSXin Li| `sampleRate` | `8000 ` `12000 ` `16000 ` `24000 ` `48000 ` | An index ranging from 0-4 is calculated using first byte of data which is used to assign value to `sampleRate` from array `kSampleRates`|
79*a58d3d2aSXin Li| `channels` (single stream)   | `1 ` `2 ` | Calculated using second byte of data |
80*a58d3d2aSXin Li| `channels` (multi stream)   | In range `1 `- `255 ` | Calculated using second byte of data |
81*a58d3d2aSXin Li
82*a58d3d2aSXin LiFollowing arguments are passed to OPUS_ENC_CTL_API:
83*a58d3d2aSXin Li
84*a58d3d2aSXin Li1. OPUS_SET_BITRATE (parameter name: `bitRate`)
85*a58d3d2aSXin Li2. OPUS_SET_COMPLEXITY (parameter name: `complexity`)
86*a58d3d2aSXin Li3. OPUS_SET_APPLICATION (parameter name: `application`)
87*a58d3d2aSXin Li4. OPUS_SET_DTX (parameter name: `setDTX`)
88*a58d3d2aSXin Li5. OPUS_SET_SIGNAL (parameter name: `signal`)
89*a58d3d2aSXin Li6. OPUS_SET_VBR (parameter name: `setVBR`)
90*a58d3d2aSXin Li7. OPUS_SET_VBR_CONSTRAINT (parameter name: `setVBRConstraint`)
91*a58d3d2aSXin Li8. OPUS_SET_FORCE_CHANNELS (parameter name: `forceChannel`)
92*a58d3d2aSXin Li9. OPUS_SET_MAX_BANDWIDTH (parameter name: `maxBandwidth`)
93*a58d3d2aSXin Li10. OPUS_SET_INBAND_FEC (parameter name: `setInbandFec`)
94*a58d3d2aSXin Li11. OPUS_SET_PACKET_LOSS_PERC (parameter name: `pktLoss`)
95*a58d3d2aSXin Li12. OPUS_SET_LSB_DEPTH (parameter name: `lsbDepth`)
96*a58d3d2aSXin Li13. OPUS_SET_PREDICTION_DISABLED (parameter name: `setPredDisable`)
97*a58d3d2aSXin Li14. OPUS_SET_EXPERT_FRAME_DURATION (parameter name: `frameSizeEnum`)
98*a58d3d2aSXin Li
99*a58d3d2aSXin Li| Parameter| Valid Values| Configured Value|
100*a58d3d2aSXin Li|------------- |-------------| ----- |
101*a58d3d2aSXin Li| `bitRate`   | In range `500 ` to `512000 ` | Calculated using all bits of 3rd, 4th and 5th byte of data |
102*a58d3d2aSXin Li| `complexity`   |0.`0 ` 1.`1 ` 2.`2 ` 3.`3 ` 4.`4 ` 5.`5 ` 6.`6 ` 7.`7 ` 8.`8 ` 9.`9 ` 10.`10 ` | Calculated using all bits of 6th byte of data |
103*a58d3d2aSXin Li| `application`   | 0.`OPUS_APPLICATION_VOIP ` 1.`OPUS_APPLICATION_AUDIO ` 2.`OPUS_APPLICATION_RESTRICTED_LOWDELAY ` | Calculated using all bits of 7th byte of data |
104*a58d3d2aSXin Li| `setDTX`   | 0.`0 ` 1.`1 ` | Calculated using bit 0 of 8th byte of data |
105*a58d3d2aSXin Li| `signal`   | 0.`OPUS_AUTO ` 1.`OPUS_SIGNAL_VOICE ` 2.`OPUS_SIGNAL_MUSIC ` | Calculated using bit 0 and bit 1 of 9th byte of data |
106*a58d3d2aSXin Li| `setVBR`   | 0.`0 ` 1.`1 `  | Calculated using bit 0 of 10th byte of data |
107*a58d3d2aSXin Li| `setVBRConstraint`   | 0.`0 ` 1.`1 ` | Calculated using bit 0 of 11th byte of data |
108*a58d3d2aSXin Li| `forceChannel`   | 0.`OPUS_AUTO ` 1.`1 ` 2.`2 ` | Calculated using all bits of 12th byte of data |
109*a58d3d2aSXin Li| `maxBandwidth`   | 0.`OPUS_BANDWIDTH_NARROWBAND ` 1.`OPUS_BANDWIDTH_MEDIUMBAND ` 2.`OPUS_BANDWIDTH_WIDEBAND ` 3.`OPUS_BANDWIDTH_SUPERWIDEBAND ` 4.`OPUS_BANDWIDTH_FULLBAND ` | Calculated using all bits of 13th byte of data |
110*a58d3d2aSXin Li| `setInbandFec`   | 0.`0 ` 1.`1 ` | Calculated using bit 0 of 14th byte of data |
111*a58d3d2aSXin Li| `pktLoss`   | 0.`0 ` 1.`1 ` 2.`2 ` 3.`5 `| Calculated using all bits of 15th byte of data |
112*a58d3d2aSXin Li| `lsbDepth`   | 0.`8 ` 1.`24 ` | Calculated using bit 0 of 16th byte of data |
113*a58d3d2aSXin Li| `setPredDisable`   | 0.`0 ` 1.`1 ` | Calculated using bit 0 of 17th byte of data |
114*a58d3d2aSXin Li| `frameSizeEnum`   | 0.`OPUS_FRAMESIZE_2_5_MS ` 1.`OPUS_FRAMESIZE_5_MS ` 2.`OPUS_FRAMESIZE_10_MS ` 3.`OPUS_FRAMESIZE_20_MS ` 4.`OPUS_FRAMESIZE_40_MS ` 5.`OPUS_FRAMESIZE_60_MS ` 6.`OPUS_FRAMESIZE_80_MS ` 7.`OPUS_FRAMESIZE_100_MS ` 8.`OPUS_FRAMESIZE_120_MS ` | Calculated using all bits of 18th byte of data |
115*a58d3d2aSXin Li
116*a58d3d2aSXin Li
117*a58d3d2aSXin Li##### Maximize utilization of input data
118*a58d3d2aSXin LiThe plugin feeds the entire input data to the codec. For buffer size which is not a multiple of mNumPcmBytesPerInputFrame, we will accumulate the input and keep it. Once the input is filled with expected number of bytes, we will send it to encoder. This ensures that the plugin tolerates any kind of input (empty, huge,
119*a58d3d2aSXin Limalformed, etc) and doesnt `exit()` on any input and thereby increasing the chance of identifying vulnerabilities.
120*a58d3d2aSXin Li
121*a58d3d2aSXin Li## Build
122*a58d3d2aSXin Li
123*a58d3d2aSXin LiThis describes steps to build opus_enc_fuzzer and opus_multistream_enc_fuzzer.
124*a58d3d2aSXin Li
125*a58d3d2aSXin Li## Android
126*a58d3d2aSXin Li
127*a58d3d2aSXin Li### Steps to build
128*a58d3d2aSXin LiBuild the fuzzer
129*a58d3d2aSXin Li```
130*a58d3d2aSXin Li  $ mm -j$(nproc) opus_enc_fuzzer
131*a58d3d2aSXin Li  $ mm -j$(nproc) opus_multistream_enc_fuzzer
132*a58d3d2aSXin Li```
133*a58d3d2aSXin Li
134*a58d3d2aSXin Li### Steps to run
135*a58d3d2aSXin LiCreate a directory CORPUS_DIR and copy some raw media files to that folder.
136*a58d3d2aSXin LiPush this directory to device.
137*a58d3d2aSXin Li
138*a58d3d2aSXin LiTo run on device
139*a58d3d2aSXin Li```
140*a58d3d2aSXin Li  $ adb sync data
141*a58d3d2aSXin Li  $ adb shell /data/fuzz/arm64/opus_enc_fuzzer/opus_enc_fuzzer CORPUS_DIR
142*a58d3d2aSXin Li  $ adb shell /data/fuzz/arm64/opus_multistream_enc_fuzzer/opus_multistream_enc_fuzzer CORPUS_DIR
143*a58d3d2aSXin Li```
144*a58d3d2aSXin LiTo run on host
145*a58d3d2aSXin Li```
146*a58d3d2aSXin Li  $ $ANDROID_HOST_OUT/fuzz/x86_64/opus_enc_fuzzer/opus_enc_fuzzer CORPUS_DIR
147*a58d3d2aSXin Li  $ $ANDROID_HOST_OUT/fuzz/x86_64/opus_multistream_enc_fuzzer/opus_multistream_enc_fuzzer CORPUS_DIR
148*a58d3d2aSXin Li```
149*a58d3d2aSXin Li
150*a58d3d2aSXin Li## References:
151*a58d3d2aSXin Li * http://llvm.org/docs/LibFuzzer.html
152*a58d3d2aSXin Li * https://github.com/google/oss-fuzz
153