1*600f14f4SXin Li# Fuzzer for libFLAC decoder 2*600f14f4SXin Li 3*600f14f4SXin Li## Plugin Design Considerations 4*600f14f4SXin LiThe fuzzer plugin for FLAC decoder is designed based on the understanding of the 5*600f14f4SXin Licodec and tries to achieve the following: 6*600f14f4SXin Li 7*600f14f4SXin Li##### Maximize code coverage 8*600f14f4SXin LiThe configuration parameters are not hardcoded, but instead selected based on 9*600f14f4SXin Liincoming data. This ensures more code paths are reached by the fuzzer. 10*600f14f4SXin Li 11*600f14f4SXin LiFLAC supports the following two decoder API's for native mode: 12*600f14f4SXin Li1. FLAC__stream_decoder_process_single (frame by frame decoding) 13*600f14f4SXin Li2. FLAC__stream_decoder_process_until_end_of_stream (decoding entire stream) 14*600f14f4SXin Li 15*600f14f4SXin LiOne of these two decoder API's will be called based on LSB of 5th byte of data. 16*600f14f4SXin Li 17*600f14f4SXin LiThis also ensures that the plugin is always deterministic for any given input. 18*600f14f4SXin Li 19*600f14f4SXin Li##### Maximize utilization of input data 20*600f14f4SXin LiThe plugin feeds the input data to the codec using a read_callback as and when 21*600f14f4SXin Lirequested by the decoder. The read_callback feeds the input data to the decoder 22*600f14f4SXin Liuntil the end of stream. 23*600f14f4SXin Li 24*600f14f4SXin LiThis ensures that the plugin tolerates any kind of input (empty, huge, 25*600f14f4SXin Limalformed, etc) and doesnt `exit()` on any input and thereby increasing the 26*600f14f4SXin Lichance of identifying vulnerabilities. 27*600f14f4SXin Li 28*600f14f4SXin Li## Build 29*600f14f4SXin Li 30*600f14f4SXin LiThis describes steps to build flac_dec_fuzzer binary. 31*600f14f4SXin Li 32*600f14f4SXin Li### Android 33*600f14f4SXin Li 34*600f14f4SXin Li#### Steps to build 35*600f14f4SXin LiBuild the fuzzer 36*600f14f4SXin Li``` 37*600f14f4SXin Li $ mm -j$(nproc) flac_dec_fuzzer 38*600f14f4SXin Li``` 39*600f14f4SXin Li 40*600f14f4SXin Li#### Steps to run 41*600f14f4SXin LiCreate a directory CORPUS_DIR and copy some flac files to that folder 42*600f14f4SXin LiPush this directory to device. 43*600f14f4SXin Li 44*600f14f4SXin LiTo run on device 45*600f14f4SXin Li``` 46*600f14f4SXin Li $ adb sync data 47*600f14f4SXin Li $ adb shell /data/fuzz/arm64/flac_dec_fuzzer/flac_dec_fuzzer CORPUS_DIR 48*600f14f4SXin Li``` 49*600f14f4SXin LiTo run on host 50*600f14f4SXin Li``` 51*600f14f4SXin Li $ $ANDROID_HOST_OUT/fuzz/x86_64/flac_dec_fuzzer/flac_dec_fuzzer CORPUS_DIR 52*600f14f4SXin Li``` 53*600f14f4SXin Li 54*600f14f4SXin Li# Fuzzer for libFLAC encoder 55*600f14f4SXin Li 56*600f14f4SXin Li## Plugin Design Considerations 57*600f14f4SXin LiThe fuzzer plugin for flac encoder is designed based on the understanding of the 58*600f14f4SXin Licodec and tries to achieve the following: 59*600f14f4SXin Li 60*600f14f4SXin Li##### Maximize code coverage 61*600f14f4SXin Li 62*600f14f4SXin LiThe configuration parameters are not hardcoded, but instead selected based on 63*600f14f4SXin Liincoming data. This ensures more code paths are reached by the fuzzer. 64*600f14f4SXin Li 65*600f14f4SXin LiFollwing functions were called in initEncoder to configure the encoder: 66*600f14f4SXin Li 67*600f14f4SXin Li| Function name | Parameter| Valid Values| Configured Value| 68*600f14f4SXin Li|------------- |------------- |-------------| ----- | 69*600f14f4SXin Li| `FLAC__stream_encoder_set_sample_rate` | sampleRate |`1 ` to `655350 ` | All the bits of 1st, 2nd and 3rd byte of data | 70*600f14f4SXin Li| `FLAC__stream_encoder_set_channels` | mChannels |`1 ` `2 ` | bit 0 of 4th byte of data | 71*600f14f4SXin Li| `FLAC__stream_encoder_set_compression_level` | compression |`1 ` `2 ` | bit 0 of 5th byte of data | 72*600f14f4SXin Li| `FLAC__stream_encoder_set_bits_per_sample` | bitsPerSample |`16 ` `24 ` | bit 0 of 6th byte of data | 73*600f14f4SXin Li| `FLAC__stream_encoder_set_verify` | - |`false ` `true ` | bit 0 of 7th byte of data | 74*600f14f4SXin Li| `FLAC__stream_encoder_set_streamable_subset` | - |`false ` `true ` | bit 0 of 8th byte of data | 75*600f14f4SXin Li| `FLAC__stream_encoder_set_do_mid_side_stereo` | - |`false ` `true ` | bit 0 of 9th byte of data | 76*600f14f4SXin Li| `FLAC__stream_encoder_set_loose_mid_side_stereo` | - |`false ` `true ` | bit 0 of 10th byte of data | 77*600f14f4SXin Li| `FLAC__stream_encoder_set_max_lpc_order` | - |`false ` `true ` | bit 0 of 11th byte of data| 78*600f14f4SXin Li| `FLAC__stream_encoder_set_qlp_coeff_precision` | - |`0 ` `1 ` | bit 0 of 12th byte of data | 79*600f14f4SXin Li| `FLAC__stream_encoder_set_do_qlp_coeff_prec_search` | - |`false ` `true ` | bit 0 of 13th byte of data | 80*600f14f4SXin Li| `FLAC__stream_encoder_set_do_escape_coding` | - |`false ` `true ` | bit 0 of 14th byte of data| 81*600f14f4SXin Li| `FLAC__stream_encoder_set_do_exhaustive_model_search` | - |`false ` `true ` | bit 0 of 15th byte of data | 82*600f14f4SXin Li| `FLAC__stream_encoder_set_min_residual_partition_order` | - |`0 ` `1 ` | bit 0 of 16th byte of data | 83*600f14f4SXin Li| `FLAC__stream_encoder_set_max_residual_partition_order` | - |`0 ` `1 ` | bit 0 of 17th byte of data | 84*600f14f4SXin Li| `FLAC__stream_encoder_set_rice_parameter_search_dist` | - |`0 ` `1 ` | bit 0 of 18th byte of data| 85*600f14f4SXin Li| `FLAC__stream_encoder_set_total_samples_estimate` | - |`0 ` `1 ` | bit 0 of 19th byte of data| 86*600f14f4SXin Li 87*600f14f4SXin Li 88*600f14f4SXin Li##### Maximize utilization of input data 89*600f14f4SXin LiThe plugin feeds the entire input data to the codec and continues with the encoding even on a failure. This ensures that the plugin tolerates any kind of input (empty, huge, malformed, etc) and doesn't `exit()` on any input and thereby increasing the chance of identifying vulnerabilities. 90*600f14f4SXin Li 91*600f14f4SXin Li## Build 92*600f14f4SXin Li 93*600f14f4SXin LiThis describes steps to build flac_enc_fuzzer binary. 94*600f14f4SXin Li 95*600f14f4SXin Li## Android 96*600f14f4SXin Li 97*600f14f4SXin Li### Steps to build 98*600f14f4SXin LiBuild the fuzzer 99*600f14f4SXin Li``` 100*600f14f4SXin Li $ mm -j$(nproc) flac_enc_fuzzer 101*600f14f4SXin Li``` 102*600f14f4SXin Li 103*600f14f4SXin Li### Steps to run 104*600f14f4SXin LiCreate a directory CORPUS_DIR and copy some wav files to that folder. 105*600f14f4SXin LiPush this directory to device. 106*600f14f4SXin Li 107*600f14f4SXin LiTo run on device 108*600f14f4SXin Li``` 109*600f14f4SXin Li $ adb sync data 110*600f14f4SXin Li $ adb shell /data/fuzz/arm64/flac_enc_fuzzer/flac_enc_fuzzer CORPUS_DIR 111*600f14f4SXin Li``` 112*600f14f4SXin LiTo run on host 113*600f14f4SXin Li``` 114*600f14f4SXin Li $ $ANDROID_HOST_OUT/fuzz/x86_64/flac_enc_fuzzer/flac_enc_fuzzer CORPUS_DIR 115*600f14f4SXin Li``` 116*600f14f4SXin Li 117*600f14f4SXin Li## References: 118*600f14f4SXin Li * http://llvm.org/docs/LibFuzzer.html 119*600f14f4SXin Li * https://github.com/google/oss-fuzz 120