aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fuzzer/Android.bp39
-rw-r--r--fuzzer/README.md59
-rw-r--r--fuzzer/aac_dec_fuzzer.cpp84
3 files changed, 182 insertions, 0 deletions
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
new file mode 100644
index 0000000..ae01dad
--- /dev/null
+++ b/fuzzer/Android.bp
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+ name: "aac_dec_fuzzer",
+ host_supported:true,
+
+ static_libs: [
+ "libFraunhoferAAC",
+ "liblog",
+ ],
+
+ srcs: [
+ "aac_dec_fuzzer.cpp",
+ ],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
diff --git a/fuzzer/README.md b/fuzzer/README.md
new file mode 100644
index 0000000..d99bc75
--- /dev/null
+++ b/fuzzer/README.md
@@ -0,0 +1,59 @@
+# Fuzzer for libFraunhoferAAC decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for aac decoder is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+
+This fuzzer makes use of the following config parameters:
+1. Transport type (parameter name: `TRANSPORT_TYPE`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `TRANSPORT_TYPE` | 0.`TT_UNKNOWN ` 1.`TT_MP4_RAW ` 2.`TT_MP4_ADIF ` 3.`TT_MP4_ADTS ` 4.`TT_MP4_LATM_MCP1 ` 5.`TT_MP4_LATM_MCP0 ` 6.`TT_MP4_LOAS ` 7.`TT_DRM ` | `TT_MP4_ADIF ` |
+
+Note: Value of `TRANSPORT_TYPE` could be set to any of these values.
+It is set to `TT_MP4_ADIF` in the fuzzer plugin.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+ * If the decode operation was successful, the input is advanced by an
+ offset calculated using valid bytes.
+ * If the decode operation was un-successful, the input is advanced by 1 byte
+ till it reaches a valid frame or end of stream.
+
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build aac_dec_fuzzer binary.
+
+## Android
+
+### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) aac_dec_fuzzer
+```
+
+### Steps to run
+Create a directory CORPUS_DIR and copy some aac files to that folder.
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
+
diff --git a/fuzzer/aac_dec_fuzzer.cpp b/fuzzer/aac_dec_fuzzer.cpp
new file mode 100644
index 0000000..686c42f
--- /dev/null
+++ b/fuzzer/aac_dec_fuzzer.cpp
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdint.h>
+#include "aacdecoder_lib.h"
+
+constexpr uint8_t kNumberOfLayers = 1;
+constexpr uint8_t kMaxChannelCount = 8;
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+ bool initDecoder();
+ void decodeFrames(UCHAR *data, UINT size);
+ void deInitDecoder();
+
+ private:
+ HANDLE_AACDECODER mAacDecoderHandle = nullptr;
+ AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
+};
+
+bool Codec::initDecoder() {
+ mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
+ if (!mAacDecoderHandle) {
+ return false;
+ }
+ return true;
+}
+
+void Codec::deInitDecoder() {
+ aacDecoder_Close(mAacDecoderHandle);
+ mAacDecoderHandle = nullptr;
+}
+
+void Codec::decodeFrames(UCHAR *data, UINT size) {
+ while (size > 0) {
+ UINT inputSize = size;
+ UINT valid = size;
+ mErrorCode = aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
+ if (mErrorCode != AAC_DEC_OK) {
+ ++data;
+ --size;
+ } else {
+ INT_PCM outputBuf[2048 * kMaxChannelCount];
+ aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, 2048 * kMaxChannelCount, 0);
+ if (valid >= inputSize) {
+ return;
+ }
+ UINT offset = inputSize - valid;
+ data += offset;
+ size = valid;
+ }
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ Codec *codec = new Codec();
+ if (!codec) {
+ return 0;
+ }
+ if (codec->initDecoder()) {
+ codec->decodeFrames((UCHAR *)(data), static_cast<UINT>(size));
+ }
+ delete codec;
+ return 0;
+}