Merge "libmediaplayerservice: Build both shared and static libraries"
diff --git a/METADATA b/METADATA
index 1fbda08..aabda36 100644
--- a/METADATA
+++ b/METADATA
@@ -2,6 +2,22 @@
# CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
# DEPENDING ON IT IN YOUR PROJECT. ***
third_party {
- # would be NOTICE save for drm/mediadrm/plugins/clearkey/hidl/
+ # would be NOTICE save for Widevine Master License Agreement in:
+ # drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp
+ # drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
+ # drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h
+ # drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto
+ # drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h
+ # and patent disclaimers in:
+ # media/codec2/components/aac/patent_disclaimer.txt
+ # media/codec2/components/amr_nb_wb/patent_disclaimer.txt
+ # media/codec2/components/mp3/patent_disclaimer.txt
+ # media/codec2/components/mpeg4_h263/patent_disclaimer.txt
+ # media/codecs/amrnb/patent_disclaimer.txt
+ # media/codecs/amrwb/dec/patent_disclaimer.txt
+ # media/codecs/amrwb/enc/patent_disclaimer.txt
+ # media/codecs/m4v_h263/patent_disclaimer.txt
+ # media/codecs/mp3dec/patent_disclaimer.txt
+ # media/libstagefright/codecs/aacenc/patent_disclaimer.txt
license_type: BY_EXCEPTION_ONLY
}
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index ab7c9af..6e9413a 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -518,9 +518,24 @@
virtual void onError(
const std::weak_ptr<Codec2Client::Component>& component,
uint32_t errorCode) override {
- // TODO
- (void)component;
- (void)errorCode;
+ {
+ // Component is only used for reporting as we use a separate listener for each instance
+ std::shared_ptr<Codec2Client::Component> comp = component.lock();
+ if (!comp) {
+ ALOGD("Component died with error: 0x%x", errorCode);
+ } else {
+ ALOGD("Component \"%s\" returned error: 0x%x", comp->getName().c_str(), errorCode);
+ }
+ }
+
+ // Report to MediaCodec
+ // Note: for now we do not propagate the error code to MediaCodec as we would need
+ // to translate to a MediaCodec error.
+ sp<CCodec> codec(mCodec.promote());
+ if (!codec || !codec->mCallback) {
+ return;
+ }
+ codec->mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
}
virtual void onDeath(
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index b112249..a26f89e 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -103,11 +103,16 @@
c2_status_t err1 = intf->querySupportedParams(¶mDescs);
if (err1 == C2_OK) {
for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
- switch ((uint32_t)desc->index()) {
- case C2StreamHdr10PlusInfo::output::PARAM_TYPE:
+ C2Param::Type type = desc->index();
+ // only consider supported parameters on raw ports
+ if (!(encoder ? type.forInput() : type.forOutput())) {
+ continue;
+ }
+ switch (type.coreIndex()) {
+ case C2StreamHdr10PlusInfo::CORE_INDEX:
supportsHdr10Plus = true;
break;
- case C2StreamHdrStaticInfo::output::PARAM_TYPE:
+ case C2StreamHdrStaticInfo::CORE_INDEX:
supportsHdr = true;
break;
default:
diff --git a/media/libeffects/preprocessing/tests/correlation.cpp b/media/libeffects/preprocessing/tests/correlation.cpp
index b13dcc7..eb56fc3 100644
--- a/media/libeffects/preprocessing/tests/correlation.cpp
+++ b/media/libeffects/preprocessing/tests/correlation.cpp
@@ -107,12 +107,19 @@
return EXIT_FAILURE;
}
- int numFrames = fileSize1 / sizeof(int16_t);
+ size_t numFrames = fileSize1 / sizeof(int16_t);
std::unique_ptr<int16_t[]> inBuffer1(new int16_t[numFrames]());
std::unique_ptr<int16_t[]> inBuffer2(new int16_t[numFrames]());
- fread(inBuffer1.get(), sizeof(int16_t), numFrames, fInput1.get());
- fread(inBuffer2.get(), sizeof(int16_t), numFrames, fInput2.get());
+ if (numFrames != fread(inBuffer1.get(), sizeof(int16_t), numFrames, fInput1.get())) {
+ printf("\nError: Unable to read %zu samples from file %s\n", numFrames, argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ if (numFrames != fread(inBuffer2.get(), sizeof(int16_t), numFrames, fInput2.get())) {
+ printf("\nError: Unable to read %zu samples from file %s\n", numFrames, argv[2]);
+ return EXIT_FAILURE;
+ }
auto pairAutoCorr1 = correlation(inBuffer1.get(), inBuffer1.get(), numFrames, enableCrossCorr);
auto pairAutoCorr2 = correlation(inBuffer2.get(), inBuffer2.get(), numFrames, enableCrossCorr);
diff --git a/media/libstagefright/tests/fuzzers/Android.bp b/media/libstagefright/tests/fuzzers/Android.bp
index 49ff69a..d39dd18 100644
--- a/media/libstagefright/tests/fuzzers/Android.bp
+++ b/media/libstagefright/tests/fuzzers/Android.bp
@@ -8,7 +8,9 @@
],
shared_libs: [
"libstagefright",
- "libstagefright_codecbase",
+ "libstagefright_codecbase",
+ "libbase",
+ "libcutils",
"libutils",
"libstagefright_foundation",
"libmedia",
@@ -16,7 +18,10 @@
"libmedia_omx",
"libgui",
"libbinder",
- "libcutils",
+ "liblog",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libstagefright",
],
}
@@ -51,3 +56,27 @@
],
defaults: ["libstagefright_fuzzer_defaults"],
}
+
+cc_fuzz {
+ name: "libstagefright_frameDecoder_fuzzer",
+ srcs: [
+ "FrameDecoderFuzzer.cpp",
+ ],
+ defaults: ["libstagefright_fuzzer_defaults"],
+}
+
+cc_fuzz {
+ name: "libstagefright_writer_fuzzer",
+ srcs: [
+ "FuzzerMediaUtility.cpp",
+ "WriterFuzzer.cpp",
+ ],
+ dictionary: "dictionaries/formats.dict",
+ defaults: ["libstagefright_fuzzer_defaults"],
+ static_libs: [
+ "libstagefright_webm",
+ "libdatasource",
+ "libstagefright_esds",
+ "libogg",
+ ],
+}
diff --git a/media/libstagefright/tests/fuzzers/FrameDecoderFuzzer.cpp b/media/libstagefright/tests/fuzzers/FrameDecoderFuzzer.cpp
new file mode 100644
index 0000000..a628c70
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/FrameDecoderFuzzer.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#include "include/FrameDecoder.h"
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/IMediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/AString.h>
+#include "FrameDecoderHelpers.h"
+#include "IMediaSourceFuzzImpl.h"
+
+namespace android {
+
+#define MAX_MEDIA_BUFFER_SIZE 2048
+
+// Fuzzer entry point.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ // Init our wrapper
+ FuzzedDataProvider fdp(data, size);
+
+ std::string name = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
+ AString componentName(name.c_str());
+ sp<MetaData> trackMeta = generateMetaData(&fdp);
+ sp<IMediaSource> source = new IMediaSourceFuzzImpl(&fdp, MAX_MEDIA_BUFFER_SIZE);
+
+ // Image or video Decoder?
+ sp<FrameDecoder> decoder;
+ bool isVideoDecoder = fdp.ConsumeBool();
+ if (isVideoDecoder) {
+ decoder = new VideoFrameDecoder(componentName, trackMeta, source);
+ } else {
+ decoder = new ImageDecoder(componentName, trackMeta, source);
+ }
+
+ while (fdp.remaining_bytes()) {
+ switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 3)) {
+ case 0:
+ decoder->init(/*frameTimeUs*/ fdp.ConsumeIntegral<int64_t>(),
+ /*option*/ fdp.ConsumeIntegral<int>(),
+ /*colorFormat*/ fdp.ConsumeIntegral<int>());
+ break;
+ case 1:
+ decoder->extractFrame();
+ break;
+ case 2: {
+ FrameRect rect;
+ rect.left = fdp.ConsumeIntegral<int32_t>();
+ rect.top = fdp.ConsumeIntegral<int32_t>();
+ rect.right = fdp.ConsumeIntegral<int32_t>();
+ rect.bottom = fdp.ConsumeIntegral<int32_t>();
+ decoder->extractFrame(&rect);
+ break;
+ }
+ case 3: {
+ sp<MetaData> trackMeta = generateMetaData(&fdp);
+ decoder->getMetadataOnly(trackMeta,
+ /*colorFormat*/ fdp.ConsumeIntegral<int>(),
+ /*thumbnail*/ fdp.ConsumeBool());
+ break;
+ }
+ }
+ }
+
+ generated_mime_types.clear();
+
+ return 0;
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/tests/fuzzers/FrameDecoderHelpers.h b/media/libstagefright/tests/fuzzers/FrameDecoderHelpers.h
new file mode 100644
index 0000000..228c04a
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/FrameDecoderHelpers.h
@@ -0,0 +1,90 @@
+
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <media/stagefright/MetaData.h>
+#include "MediaMimeTypes.h"
+
+#define MAX_METADATA_BUF_SIZE 512
+
+namespace android {
+
+std::vector<std::shared_ptr<char>> generated_mime_types;
+
+sp<MetaData> generateMetaData(FuzzedDataProvider *fdp) {
+ sp<MetaData> newMeta = new MetaData();
+
+ // random MIME Type
+ const char *mime_type;
+ size_t index = fdp->ConsumeIntegralInRange<size_t>(0, kMimeTypes.size());
+ // Let there be a chance of a true random string
+ if (index == kMimeTypes.size()) {
+ std::string mime_str = fdp->ConsumeRandomLengthString(64);
+ std::shared_ptr<char> mime_cstr(new char[mime_str.length()+1]);
+ generated_mime_types.push_back(mime_cstr);
+ strncpy(mime_cstr.get(), mime_str.c_str(), mime_str.length()+1);
+ mime_type = mime_cstr.get();
+ } else {
+ mime_type = kMimeTypes[index];
+ }
+ newMeta->setCString(kKeyMIMEType, mime_type);
+
+ // Thumbnail time
+ newMeta->setInt64(kKeyThumbnailTime, fdp->ConsumeIntegral<int64_t>());
+
+ // Values used by allocVideoFrame
+ newMeta->setInt32(kKeyRotation, fdp->ConsumeIntegral<int32_t>());
+ size_t profile_size =
+ fdp->ConsumeIntegralInRange<size_t>(0, MAX_METADATA_BUF_SIZE);
+ std::vector<uint8_t> profile_bytes =
+ fdp->ConsumeBytes<uint8_t>(profile_size);
+ newMeta->setData(kKeyIccProfile,
+ fdp->ConsumeIntegral<int32_t>(),
+ profile_bytes.empty() ? nullptr : profile_bytes.data(),
+ profile_bytes.size());
+ newMeta->setInt32(kKeySARWidth, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeySARHeight, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeyDisplayWidth, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeyDisplayHeight, fdp->ConsumeIntegral<int32_t>());
+
+ // Values used by findThumbnailInfo
+ newMeta->setInt32(kKeyThumbnailWidth, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeyThumbnailHeight, fdp->ConsumeIntegral<int32_t>());
+ size_t thumbnail_size =
+ fdp->ConsumeIntegralInRange<size_t>(0, MAX_METADATA_BUF_SIZE);
+ std::vector<uint8_t> thumb_bytes =
+ fdp->ConsumeBytes<uint8_t>(thumbnail_size);
+ newMeta->setData(kKeyThumbnailHVCC,
+ fdp->ConsumeIntegral<int32_t>(),
+ thumb_bytes.empty() ? nullptr : thumb_bytes.data(),
+ thumb_bytes.size());
+
+ // Values used by findGridInfo
+ newMeta->setInt32(kKeyTileWidth, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeyTileHeight, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeyGridRows, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeyGridCols, fdp->ConsumeIntegral<int32_t>());
+
+ // A few functions perform a CHECK() that height/width are set
+ newMeta->setInt32(kKeyHeight, fdp->ConsumeIntegral<int32_t>());
+ newMeta->setInt32(kKeyWidth, fdp->ConsumeIntegral<int32_t>());
+
+ return newMeta;
+}
+
+} // namespace android
diff --git a/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.cpp b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.cpp
new file mode 100644
index 0000000..810ae95
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright 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.
+ */
+
+#include "FuzzerMediaUtility.h"
+
+#include <media/stagefright/AACWriter.h>
+#include <media/stagefright/AMRWriter.h>
+#include <media/stagefright/MPEG2TSWriter.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/OggWriter.h>
+
+#include "MediaMimeTypes.h"
+#include "webm/WebmWriter.h"
+
+namespace android {
+std::string genMimeType(FuzzedDataProvider *dataProvider) {
+ uint8_t idx = dataProvider->ConsumeIntegralInRange<uint8_t>(0, kMimeTypes.size() - 1);
+ return std::string(kMimeTypes[idx]);
+}
+
+sp<IMediaExtractor> genMediaExtractor(FuzzedDataProvider *dataProvider, std::string mimeType,
+ uint16_t maxDataAmount) {
+ uint32_t dataBlobSize = dataProvider->ConsumeIntegralInRange<uint16_t>(0, maxDataAmount);
+ std::vector<uint8_t> data = dataProvider->ConsumeBytes<uint8_t>(dataBlobSize);
+ // data:[<mediatype>][;base64],<data>
+ std::string uri("data:");
+ uri += mimeType;
+ // Currently libstagefright only accepts base64 uris
+ uri += ";base64,";
+ android::AString out;
+ android::encodeBase64(data.data(), data.size(), &out);
+ uri += out.c_str();
+
+ sp<DataSource> source =
+ DataSourceFactory::getInstance()->CreateFromURI(NULL /* httpService */, uri.c_str());
+
+ if (source == NULL) {
+ return NULL;
+ }
+
+ return MediaExtractorFactory::Create(source);
+}
+
+sp<MediaSource> genMediaSource(FuzzedDataProvider *dataProvider, uint16_t maxMediaBlobSize) {
+ std::string mime = genMimeType(dataProvider);
+ sp<IMediaExtractor> extractor = genMediaExtractor(dataProvider, mime, maxMediaBlobSize);
+
+ if (extractor == NULL) {
+ return NULL;
+ }
+
+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
+ sp<MetaData> meta = extractor->getTrackMetaData(i);
+
+ const char *trackMime;
+ if (!strcasecmp(mime.c_str(), trackMime)) {
+ sp<IMediaSource> track = extractor->getTrack(i);
+ if (track == NULL) {
+ return NULL;
+ }
+ return new CallbackMediaSource(track);
+ }
+ }
+
+ return NULL;
+}
+
+sp<MediaWriter> createWriter(int fd, StandardWriters writerType, sp<MetaData> fileMeta) {
+ sp<MediaWriter> writer;
+ switch (writerType) {
+ case OGG:
+ writer = new OggWriter(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_OGG);
+ break;
+ case AAC:
+ writer = new AACWriter(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AAC_ADIF);
+ break;
+ case AAC_ADTS:
+ writer = new AACWriter(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AAC_ADTS);
+ break;
+ case WEBM:
+ writer = new WebmWriter(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_WEBM);
+ break;
+ case MPEG4:
+ writer = new MPEG4Writer(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_MPEG_4);
+ break;
+ case AMR_NB:
+ writer = new AMRWriter(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_NB);
+ break;
+ case AMR_WB:
+ writer = new AMRWriter(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_WB);
+ break;
+ case MPEG2TS:
+ writer = new MPEG2TSWriter(fd);
+ fileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_MPEG2TS);
+ break;
+ default:
+ return nullptr;
+ }
+ if (writer != nullptr) {
+ fileMeta->setInt32(kKeyRealTimeRecording, false);
+ }
+ return writer;
+}
+} // namespace android
\ No newline at end of file
diff --git a/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.h b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.h
new file mode 100644
index 0000000..98bfb94
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+#include <datasource/DataSourceFactory.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <android/IMediaExtractor.h>
+#include <media/IMediaHTTPService.h>
+#include <media/mediarecorder.h>
+#include <media/stagefright/CallbackMediaSource.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/MediaWriter.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/base64.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+enum StandardWriters {
+ OGG,
+ AAC,
+ AAC_ADTS,
+ WEBM,
+ MPEG4,
+ AMR_NB,
+ AMR_WB,
+ MPEG2TS,
+ // Allows FuzzedDataProvider to find the end of this enum.
+ kMaxValue = MPEG2TS,
+};
+
+std::string genMimeType(FuzzedDataProvider *dataProvider);
+sp<IMediaExtractor> genMediaExtractor(FuzzedDataProvider *dataProvider, uint16_t dataAmount);
+sp<MediaSource> genMediaSource(FuzzedDataProvider *dataProvider, uint16_t maxMediaBlobSize);
+
+sp<MediaWriter> createWriter(int32_t fd, StandardWriters writerType, sp<MetaData> fileMeta);
+} // namespace android
diff --git a/media/libstagefright/tests/fuzzers/IMediaSourceFuzzImpl.h b/media/libstagefright/tests/fuzzers/IMediaSourceFuzzImpl.h
new file mode 100644
index 0000000..e769950
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/IMediaSourceFuzzImpl.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef IMEDIASOURCEFUZZIMPL_H
+#define IMEDIASOURCEFUZZIMPL_H
+
+#include <media/stagefright/MediaSource.h>
+
+namespace android {
+
+class IMediaSourceFuzzImpl : public IMediaSource {
+ public:
+ IMediaSourceFuzzImpl(FuzzedDataProvider *_fdp, size_t _max_buffer_size) :
+ fdp(_fdp),
+ max_buffer_size(_max_buffer_size) {}
+ status_t start(MetaData*) override { return 0; }
+ status_t stop() override { return 0; }
+ sp<MetaData> getFormat() override { return nullptr; }
+ status_t read(MediaBufferBase**,
+ const MediaSource::ReadOptions*) override;
+ status_t readMultiple(Vector<MediaBufferBase*>*, uint32_t,
+ const MediaSource::ReadOptions*) override;
+ bool supportReadMultiple() override { return true; }
+ bool supportNonblockingRead() override { return true; }
+ status_t pause() override { return 0; }
+
+ protected:
+ IBinder* onAsBinder() { return nullptr; }
+
+ private:
+ FuzzedDataProvider *fdp;
+ std::vector<std::shared_ptr<MediaBufferBase>> buffer_bases;
+ const size_t max_buffer_size;
+};
+
+// This class is simply to expose the destructor
+class MediaBufferFuzzImpl : public MediaBuffer {
+ public:
+ MediaBufferFuzzImpl(void *data, size_t size) : MediaBuffer(data, size) {}
+ ~MediaBufferFuzzImpl() {}
+};
+
+status_t IMediaSourceFuzzImpl::read(MediaBufferBase **buffer,
+ const MediaSource::ReadOptions *options) {
+ Vector<MediaBufferBase*> buffers;
+ status_t ret = readMultiple(&buffers, 1, options);
+ *buffer = buffers.empty() ? nullptr : buffers[0];
+
+ return ret;
+}
+
+status_t IMediaSourceFuzzImpl::readMultiple(Vector<MediaBufferBase*>* buffers,
+ uint32_t maxNumBuffers, const MediaSource::ReadOptions*) {
+ uint32_t num_buffers =
+ fdp->ConsumeIntegralInRange<uint32_t>(0, maxNumBuffers);
+ for(uint32_t i = 0; i < num_buffers; i++) {
+ std::vector<uint8_t> buf = fdp->ConsumeBytes<uint8_t>(
+ fdp->ConsumeIntegralInRange<size_t>(0, max_buffer_size));
+
+ std::shared_ptr<MediaBufferBase> mbb(
+ new MediaBufferFuzzImpl(buf.data(), buf.size()));
+
+ buffer_bases.push_back(mbb);
+ buffers->push_back(mbb.get());
+ }
+
+ // STATUS_OK
+ return 0;
+}
+
+} // namespace android
+
+#endif // IMEDIASOURCEFUZZIMPL_H
+
diff --git a/media/libstagefright/tests/fuzzers/MediaClockFuzzer.cpp b/media/libstagefright/tests/fuzzers/MediaClockFuzzer.cpp
index e473541..9b26f0b 100644
--- a/media/libstagefright/tests/fuzzers/MediaClockFuzzer.cpp
+++ b/media/libstagefright/tests/fuzzers/MediaClockFuzzer.cpp
@@ -17,52 +17,53 @@
// dylan.katz@leviathansecurity.com
#include <fuzzer/FuzzedDataProvider.h>
-#include <media/stagefright/MediaClock.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaClock.h>
namespace android {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- sp<MediaClock> mClock(new MediaClock);
+ FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+ sp<MediaClock> mClock(new MediaClock);
- bool registered = false;
- while (fdp.remaining_bytes() > 0) {
- switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 5)) {
- case 0: {
- if (registered == false) {
- mClock->init();
- registered = true;
- }
- break;
+ bool registered = false;
+ while (fdp.remaining_bytes() > 0) {
+ switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 5)) {
+ case 0: {
+ if (registered == false) {
+ mClock->init();
+ registered = true;
+ }
+ break;
+ }
+ case 1: {
+ int64_t startingTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
+ mClock->setStartingTimeMedia(startingTimeMediaUs);
+ break;
+ }
+ case 2: {
+ mClock->clearAnchor();
+ break;
+ }
+ case 3: {
+ int64_t anchorTimeRealUs = fdp.ConsumeIntegral<int64_t>();
+ int64_t anchorTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
+ int64_t maxTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
+ mClock->updateAnchor(anchorTimeMediaUs, anchorTimeRealUs,
+ maxTimeMediaUs);
+ break;
+ }
+ case 4: {
+ int64_t maxTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
+ mClock->updateMaxTimeMedia(maxTimeMediaUs);
+ break;
+ }
+ case 5: {
+ wp<AMessage> msg(new AMessage);
+ mClock->setNotificationMessage(msg.promote());
+ }
+ }
}
- case 1: {
- int64_t startingTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
- mClock->setStartingTimeMedia(startingTimeMediaUs);
- break;
- }
- case 2: {
- mClock->clearAnchor();
- break;
- }
- case 3: {
- int64_t anchorTimeRealUs = fdp.ConsumeIntegral<int64_t>();
- int64_t anchorTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
- int64_t maxTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
- mClock->updateAnchor(anchorTimeMediaUs, anchorTimeRealUs, maxTimeMediaUs);
- break;
- }
- case 4: {
- int64_t maxTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
- mClock->updateMaxTimeMedia(maxTimeMediaUs);
- break;
- }
- case 5: {
- wp<AMessage> msg(new AMessage);
- mClock->setNotificationMessage(msg.promote());
- }
- }
- }
- return 0;
+ return 0;
}
-} // namespace android
+} // namespace android
diff --git a/media/libstagefright/tests/fuzzers/MediaMimeTypes.h b/media/libstagefright/tests/fuzzers/MediaMimeTypes.h
new file mode 100644
index 0000000..9f337ac
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/MediaMimeTypes.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef FUZZER_MEDIAMIMETYPES_H_
+#define FUZZER_MEDIAMIMETYPES_H_
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+namespace android {
+
+static const std::vector<const char*> kMimeTypes {
+ MEDIA_MIMETYPE_IMAGE_JPEG,
+ MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC,
+ MEDIA_MIMETYPE_VIDEO_VP8,
+ MEDIA_MIMETYPE_VIDEO_VP9,
+ MEDIA_MIMETYPE_VIDEO_AV1,
+ MEDIA_MIMETYPE_VIDEO_AVC,
+ MEDIA_MIMETYPE_VIDEO_HEVC,
+ MEDIA_MIMETYPE_VIDEO_MPEG4,
+ MEDIA_MIMETYPE_VIDEO_H263,
+ MEDIA_MIMETYPE_VIDEO_MPEG2,
+ MEDIA_MIMETYPE_VIDEO_RAW,
+ MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
+ MEDIA_MIMETYPE_VIDEO_SCRAMBLED,
+ MEDIA_MIMETYPE_VIDEO_DIVX,
+ MEDIA_MIMETYPE_VIDEO_DIVX3,
+ MEDIA_MIMETYPE_VIDEO_XVID,
+ MEDIA_MIMETYPE_VIDEO_MJPEG,
+ MEDIA_MIMETYPE_AUDIO_AMR_NB,
+ MEDIA_MIMETYPE_AUDIO_AMR_WB,
+ MEDIA_MIMETYPE_AUDIO_MPEG,
+ MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
+ MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
+ MEDIA_MIMETYPE_AUDIO_MIDI,
+ MEDIA_MIMETYPE_AUDIO_AAC,
+ MEDIA_MIMETYPE_AUDIO_QCELP,
+ MEDIA_MIMETYPE_AUDIO_VORBIS,
+ MEDIA_MIMETYPE_AUDIO_OPUS,
+ MEDIA_MIMETYPE_AUDIO_G711_ALAW,
+ MEDIA_MIMETYPE_AUDIO_G711_MLAW,
+ MEDIA_MIMETYPE_AUDIO_RAW,
+ MEDIA_MIMETYPE_AUDIO_FLAC,
+ MEDIA_MIMETYPE_AUDIO_AAC_ADTS,
+ MEDIA_MIMETYPE_AUDIO_MSGSM,
+ MEDIA_MIMETYPE_AUDIO_AC3,
+ MEDIA_MIMETYPE_AUDIO_EAC3,
+ MEDIA_MIMETYPE_AUDIO_EAC3_JOC,
+ MEDIA_MIMETYPE_AUDIO_AC4,
+ MEDIA_MIMETYPE_AUDIO_SCRAMBLED,
+ MEDIA_MIMETYPE_AUDIO_ALAC,
+ MEDIA_MIMETYPE_AUDIO_WMA,
+ MEDIA_MIMETYPE_AUDIO_MS_ADPCM,
+ MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM,
+ MEDIA_MIMETYPE_CONTAINER_MPEG4,
+ MEDIA_MIMETYPE_CONTAINER_WAV,
+ MEDIA_MIMETYPE_CONTAINER_OGG,
+ MEDIA_MIMETYPE_CONTAINER_MATROSKA,
+ MEDIA_MIMETYPE_CONTAINER_MPEG2TS,
+ MEDIA_MIMETYPE_CONTAINER_AVI,
+ MEDIA_MIMETYPE_CONTAINER_MPEG2PS,
+ MEDIA_MIMETYPE_CONTAINER_HEIF,
+ MEDIA_MIMETYPE_TEXT_3GPP,
+ MEDIA_MIMETYPE_TEXT_SUBRIP,
+ MEDIA_MIMETYPE_TEXT_VTT,
+ MEDIA_MIMETYPE_TEXT_CEA_608,
+ MEDIA_MIMETYPE_TEXT_CEA_708,
+ MEDIA_MIMETYPE_DATA_TIMED_ID3
+};
+
+} // namespace android
+
+#endif // FUZZER_MEDIAMIMETYPES_H_
diff --git a/media/libstagefright/tests/fuzzers/StagefrightMediaScannerFuzzer.cpp b/media/libstagefright/tests/fuzzers/StagefrightMediaScannerFuzzer.cpp
index a072b7c..c50c951 100644
--- a/media/libstagefright/tests/fuzzers/StagefrightMediaScannerFuzzer.cpp
+++ b/media/libstagefright/tests/fuzzers/StagefrightMediaScannerFuzzer.cpp
@@ -16,7 +16,6 @@
// Authors: corbin.souffrant@leviathansecurity.com
// dylan.katz@leviathansecurity.com
-#include <cutils/ashmem.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <media/stagefright/StagefrightMediaScanner.h>
@@ -24,59 +23,39 @@
namespace android {
class FuzzMediaScannerClient : public MediaScannerClient {
-public:
- virtual status_t scanFile(const char *, long long, long long, bool, bool) {
- return 0;
- }
+ public:
+ virtual status_t scanFile(const char*, long long, long long, bool, bool) {
+ return 0;
+ }
- virtual status_t handleStringTag(const char *, const char *) { return 0; }
+ virtual status_t handleStringTag(const char*, const char*) { return 0; }
- virtual status_t setMimeType(const char *) { return 0; }
+ virtual status_t setMimeType(const char*) { return 0; }
};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- StagefrightMediaScanner mScanner = StagefrightMediaScanner();
- // Without this, the fuzzer crashes for some reason.
- mScanner.setLocale("");
+ FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+ StagefrightMediaScanner mScanner = StagefrightMediaScanner();
+ // Without this, the fuzzer crashes for some reason.
+ mScanner.setLocale("");
- size_t data_size = fdp.ConsumeIntegralInRange<size_t>(0, size);
- int fd =
- ashmem_create_region("stagefrightmediascanner_fuzz_region", data_size);
- if (fd < 0)
+ while (fdp.remaining_bytes() > 0) {
+ switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 1)) {
+ case 0: {
+ std::string path = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
+ std::string mimeType =
+ fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
+ std::shared_ptr<MediaScannerClient> client(new FuzzMediaScannerClient());
+ mScanner.processFile(path.c_str(), mimeType.c_str(), *client);
+ break;
+ }
+ case 1: {
+ int fd = fdp.ConsumeIntegral<int>();
+ if (fd >= 0 && fd <= 2) fd = 3;
+ mScanner.extractAlbumArt(fd);
+ }
+ }
+ }
return 0;
-
- uint8_t *sh_data = static_cast<uint8_t *>(
- mmap(NULL, data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
- if (sh_data == MAP_FAILED)
- return 0;
-
- while (fdp.remaining_bytes() > 8) {
- switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 1)) {
- case 0: {
- std::string path = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
- std::string mimeType =
- fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
- std::shared_ptr<MediaScannerClient> client(new FuzzMediaScannerClient());
- mScanner.processFile(path.c_str(), mimeType.c_str(), *client);
- break;
- }
- case 1: {
- size_t to_copy = fdp.ConsumeIntegralInRange<size_t>(1, data_size);
- std::vector<uint8_t> rand_buf = fdp.ConsumeBytes<uint8_t>(to_copy);
-
- // If fdp doesn't have enough bytes left it will just make a shorter
- // vector.
- to_copy = std::min(rand_buf.size(), data_size);
-
- std::copy(sh_data, sh_data + to_copy, rand_buf.begin());
- mScanner.extractAlbumArt(fd);
- }
- }
- }
-
- munmap(sh_data, data_size);
- close(fd);
- return 0;
}
-} // namespace android
+} // namespace android
diff --git a/media/libstagefright/tests/fuzzers/WriterFuzzer.cpp b/media/libstagefright/tests/fuzzers/WriterFuzzer.cpp
new file mode 100644
index 0000000..03e9b43
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/WriterFuzzer.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright 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.
+ */
+// Authors: corbin.souffrant@leviathansecurity.com
+// dylan.katz@leviathansecurity.com
+
+#include <android-base/file.h>
+#include <ctype.h>
+#include <media/mediarecorder.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <stdlib.h>
+#include <utils/StrongPointer.h>
+#include <utils/Vector.h>
+
+#include <functional>
+#include <string>
+
+#include "FuzzerMediaUtility.h"
+#include "fuzzer/FuzzedDataProvider.h"
+
+static constexpr uint16_t kMaxOperations = 5000;
+static constexpr uint8_t kMaxPackageNameLen = 50;
+// For other strings in mpeg we want a higher limit.
+static constexpr uint16_t kMaxMPEGStrLen = 1000;
+static constexpr uint16_t kMaxMediaBlobSize = 1000;
+
+namespace android {
+
+std::string getFourCC(FuzzedDataProvider *fdp) {
+ std::string fourCC = fdp->ConsumeRandomLengthString(4);
+ // Replace any existing nulls
+ for (size_t pos = 0; pos < fourCC.length(); pos++) {
+ if (fourCC.at(pos) == '\0') {
+ fourCC.replace(pos, 1, "a");
+ }
+ }
+
+ // If our string is too short, fill the remainder with "a"s.
+ while (fourCC.length() < 4) {
+ fourCC += 'a';
+ }
+ return fourCC;
+}
+
+typedef std::vector<std::function<void(FuzzedDataProvider*,
+ sp<MediaWriter>, sp<MetaData>, int tmpFileFd)>> OperationVec;
+typedef std::vector<std::function<void(FuzzedDataProvider*, MPEG4Writer*)>> MPEG4OperationVec;
+static const OperationVec operations = {
+ [](FuzzedDataProvider*, sp<MediaWriter> mediaWriter, sp<MetaData>, int) {
+ mediaWriter->pause();
+ },
+ [](FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter, sp<MetaData>, int tmpFd) {
+ bool valid_fd = dataProvider->ConsumeBool();
+ int fd = -1;
+ if (valid_fd) {
+ fd = tmpFd;
+ }
+ // Args don't seem to be used
+ Vector<String16> args;
+ mediaWriter->dump(fd, args);
+ },
+ [](FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter, sp<MetaData>, int tmpFd) {
+ bool valid_fd = dataProvider->ConsumeBool();
+ int fd = -1;
+ if (valid_fd) {
+ fd = tmpFd;
+ }
+ mediaWriter->setNextFd(fd);
+ },
+ [](FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter, sp<MetaData>, int) {
+ mediaWriter->setCaptureRate(dataProvider->ConsumeFloatingPoint<float>());
+ },
+ [](FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter, sp<MetaData>, int) {
+ mediaWriter->setMaxFileDuration(dataProvider->ConsumeIntegral<int64_t>());
+ },
+ [](FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter, sp<MetaData>, int) {
+ mediaWriter->setStartTimeOffsetMs(dataProvider->ConsumeIntegral<int>());
+
+ // Likely won't do much, but might as well as do a quick check
+ // while we're here.
+ mediaWriter->getStartTimeOffsetMs();
+ },
+ [](FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter, sp<MetaData>, int) {
+ mediaWriter->setMaxFileDuration(dataProvider->ConsumeIntegral<int64_t>());
+ },
+ [](FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter, sp<MetaData>, int) {
+ mediaWriter->setMaxFileDuration(dataProvider->ConsumeIntegral<int64_t>());
+ },
+};
+
+static const MPEG4OperationVec mpeg4Operations = {
+ [](FuzzedDataProvider*, MPEG4Writer *mediaWriter) { mediaWriter->notifyApproachingLimit(); },
+ // Lower level write methods.
+ // High-level startBox/endBox/etc are all called elsewhere,
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ uint8_t val = dataProvider->ConsumeIntegral<uint8_t>();
+ mediaWriter->writeInt8(val);
+ },
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ uint16_t val = dataProvider->ConsumeIntegral<uint16_t>();
+ mediaWriter->writeInt16(val);
+ },
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ uint32_t val = dataProvider->ConsumeIntegral<uint32_t>();
+ mediaWriter->writeInt32(val);
+ },
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ uint64_t val = dataProvider->ConsumeIntegral<uint64_t>();
+ mediaWriter->writeInt64(val);
+ },
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ std::string strVal = dataProvider->ConsumeRandomLengthString(kMaxMPEGStrLen);
+ mediaWriter->writeCString(strVal.c_str());
+ },
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ std::string fourCC = getFourCC(dataProvider);
+ mediaWriter->writeFourcc(fourCC.c_str());
+ },
+
+ // Misc setters
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ uint32_t layers = dataProvider->ConsumeIntegral<uint32_t>();
+ mediaWriter->setTemporalLayerCount(layers);
+ },
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ uint32_t duration = dataProvider->ConsumeIntegral<uint32_t>();
+ mediaWriter->setInterleaveDuration(duration);
+ },
+ [](FuzzedDataProvider *dataProvider, MPEG4Writer *mediaWriter) {
+ int lat = dataProvider->ConsumeIntegral<int>();
+ int lon = dataProvider->ConsumeIntegral<int>();
+ mediaWriter->setGeoData(lat, lon);
+ },
+};
+
+// Not all writers can always add new sources, so we'll need additional checks.
+void addSource(FuzzedDataProvider *dataProvider, sp<MediaWriter> mediaWriter) {
+ sp<MediaSource> mediaSource = genMediaSource(dataProvider, kMaxMediaBlobSize);
+ if (mediaSource == NULL) {
+ // There's a static check preventing NULLs in addSource.
+ return;
+ }
+ mediaWriter->addSource(mediaSource);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ FuzzedDataProvider dataProvider(data, size);
+ TemporaryFile tf;
+ sp<MetaData> fileMeta = new MetaData;
+ StandardWriters writerType = dataProvider.ConsumeEnum<StandardWriters>();
+ sp<MediaWriter> writer = createWriter(tf.fd, writerType, fileMeta);
+
+ std::string packageName = dataProvider.ConsumeRandomLengthString(kMaxPackageNameLen);
+
+ sp<MediaRecorder> mr = new MediaRecorder(String16(packageName.c_str()));
+ writer->setListener(mr);
+
+ uint8_t baseOpLen = operations.size();
+ uint8_t totalLen = baseOpLen;
+ uint8_t maxSources;
+ // Different writers support different amounts of sources.
+ switch (writerType) {
+ case StandardWriters::AAC:
+ case StandardWriters::AAC_ADTS:
+ case StandardWriters::AMR_NB:
+ case StandardWriters::AMR_WB:
+ case StandardWriters::OGG:
+ maxSources = 1;
+ break;
+ case StandardWriters::WEBM:
+ maxSources = 2;
+ break;
+ default:
+ maxSources = UINT8_MAX;
+ break;
+ }
+ // Initialize some number of sources and add them to our writer.
+ uint8_t sourceCount = dataProvider.ConsumeIntegralInRange<uint8_t>(0, maxSources);
+ for (uint8_t i = 0; i < sourceCount; i++) {
+ addSource(&dataProvider, writer);
+ }
+
+ // Increase our range if additional operations are implemented.
+ // Currently only MPEG4 has additiona public operations on their writer.
+ if (writerType == StandardWriters::MPEG4) {
+ totalLen += mpeg4Operations.size();
+ }
+
+ // Many operations require the writer to be started.
+ writer->start(fileMeta.get());
+ for (size_t ops_run = 0; dataProvider.remaining_bytes() > 0 && ops_run < kMaxOperations - 1;
+ ops_run++) {
+ uint8_t op = dataProvider.ConsumeIntegralInRange<uint8_t>(0, totalLen - 1);
+ if (op < baseOpLen) {
+ operations[op](&dataProvider, writer, fileMeta, tf.fd);
+ } else if (writerType == StandardWriters::MPEG4) {
+ mpeg4Operations[op - baseOpLen](&dataProvider, (MPEG4Writer*)writer.get());
+ } else {
+ // Here just in case, will error out.
+ operations[op](&dataProvider, writer, fileMeta, tf.fd);
+ }
+ }
+ writer->stop();
+
+ writer.clear();
+ writer = nullptr;
+ return 0;
+}
+} // namespace android
diff --git a/media/libstagefright/tests/fuzzers/dictionaries/formats.dict b/media/libstagefright/tests/fuzzers/dictionaries/formats.dict
new file mode 100644
index 0000000..4ab22de
--- /dev/null
+++ b/media/libstagefright/tests/fuzzers/dictionaries/formats.dict
@@ -0,0 +1,299 @@
+############################################################################################################
+# This file is a combination of these dictionaries: #
+# https://github.com/google/fuzzing/blob/0c48531c4d317cea9479b3ec1b0ddb9edc438c3a/dictionaries/mp4.dict #
+# https://github.com/google/fuzzing/blob/0c48531c4d317cea9479b3ec1b0ddb9edc438c3a/dictionaries/webm.dict #
+# https://github.com/google/fuzzing/blob/0c48531c4d317cea9479b3ec1b0ddb9edc438c3a/dictionaries/ogg.dict #
+# MPEG4, OGG, and WEBM are all formats used by MediaWriter. #
+############################################################################################################
+# mp4.dict
+# Taken from https://chromium.googlesource.com/chromium/src/+/master/media/test/mp4.dict
+FOURCC_NULL="\x00\x00\x00\x00"
+FOURCC_AC3 ="\x61\x63\x2d\x33"
+FOURCC_EAC3="\x65\x63\x2d\x33"
+FOURCC_AVC1="\x61\x76\x63\x31"
+FOURCC_AVC3="\x61\x76\x63\x33"
+FOURCC_AVCC="\x61\x76\x63\x43"
+FOURCC_BLOC="\x62\x6C\x6F\x63"
+FOURCC_CENC="\x63\x65\x6e\x63"
+FOURCC_CO64="\x63\x6f\x36\x34"
+FOURCC_CTTS="\x63\x74\x74\x73"
+FOURCC_DINF="\x64\x69\x6e\x66"
+FOURCC_EDTS="\x65\x64\x74\x73"
+FOURCC_EMSG="\x65\x6d\x73\x67"
+FOURCC_ELST="\x65\x6c\x73\x74"
+FOURCC_ENCA="\x65\x6e\x63\x61"
+FOURCC_ENCV="\x65\x6e\x63\x76"
+FOURCC_ESDS="\x65\x73\x64\x73"
+FOURCC_FREE="\x66\x72\x65\x65"
+FOURCC_FRMA="\x66\x72\x6d\x61"
+FOURCC_FTYP="\x66\x74\x79\x70"
+FOURCC_HDLR="\x68\x64\x6c\x72"
+FOURCC_HINT="\x68\x69\x6e\x74"
+FOURCC_HVC1="\x68\x76\x63\x31"
+FOURCC_HVCC="\x68\x76\x63\x43"
+FOURCC_IODS="\x69\x6f\x64\x73"
+FOURCC_MDAT="\x6d\x64\x61\x74"
+FOURCC_MDHD="\x6d\x64\x68\x64"
+FOURCC_MDIA="\x6d\x64\x69\x61"
+FOURCC_MECO="\x6d\x65\x63\x6f"
+FOURCC_MEHD="\x6d\x65\x68\x64"
+FOURCC_META="\x6d\x65\x74\x61"
+FOURCC_MFHD="\x6d\x66\x68\x64"
+FOURCC_MFRA="\x6d\x66\x72\x61"
+FOURCC_MINF="\x6d\x69\x6e\x66"
+FOURCC_MOOF="\x6d\x6f\x6f\x66"
+FOURCC_MOOV="\x6d\x6f\x6f\x76"
+FOURCC_MP4A="\x6d\x70\x34\x61"
+FOURCC_MP4V="\x6d\x70\x34\x76"
+FOURCC_MVEX="\x6d\x76\x65\x78"
+FOURCC_MVHD="\x6d\x76\x68\x64"
+FOURCC_PASP="\x70\x61\x73\x70"
+FOURCC_PDIN="\x70\x64\x69\x6e"
+FOURCC_PRFT="\x70\x72\x66\x74"
+FOURCC_PSSH="\x70\x73\x73\x68"
+FOURCC_SAIO="\x73\x61\x69\x6f"
+FOURCC_SAIZ="\x73\x61\x69\x7a"
+FOURCC_SBGP="\x73\x62\x67\x70"
+FOURCC_SCHI="\x73\x63\x68\x69"
+FOURCC_SCHM="\x73\x63\x68\x6d"
+FOURCC_SDTP="\x73\x64\x74\x70"
+FOURCC_SEIG="\x73\x65\x69\x67"
+FOURCC_SENC="\x73\x65\x6e\x63"
+FOURCC_SGPD="\x73\x67\x70\x64"
+FOURCC_SIDX="\x73\x69\x64\x78"
+FOURCC_SINF="\x73\x69\x6e\x66"
+FOURCC_SKIP="\x73\x6b\x69\x70"
+FOURCC_SMHD="\x73\x6d\x68\x64"
+FOURCC_SOUN="\x73\x6f\x75\x6e"
+FOURCC_SSIX="\x73\x73\x69\x78"
+FOURCC_STBL="\x73\x74\x62\x6c"
+FOURCC_STCO="\x73\x74\x63\x6f"
+FOURCC_STSC="\x73\x74\x73\x63"
+FOURCC_STSD="\x73\x74\x73\x64"
+FOURCC_STSS="\x73\x74\x73\x73"
+FOURCC_STSZ="\x73\x74\x73\x7a"
+FOURCC_STTS="\x73\x74\x74\x73"
+FOURCC_STYP="\x73\x74\x79\x70"
+FOURCC_TENC="\x74\x65\x6e\x63"
+FOURCC_TFDT="\x74\x66\x64\x74"
+FOURCC_TFHD="\x74\x66\x68\x64"
+FOURCC_TKHD="\x74\x6b\x68\x64"
+FOURCC_TRAF="\x74\x72\x61\x66"
+FOURCC_TRAK="\x74\x72\x61\x6b"
+FOURCC_TREX="\x74\x72\x65\x78"
+FOURCC_TRUN="\x74\x72\x75\x6e"
+FOURCC_UDTA="\x75\x64\x74\x61"
+FOURCC_UUID="\x75\x75\x69\x64"
+FOURCC_VIDE="\x76\x69\x64\x65"
+FOURCC_VMHD="\x76\x6d\x68\x64"
+FOURCC_WIDE="\x77\x69\x64\x65"
+
+# ogg.dict
+# https://xiph.org/vorbis/doc/Vorbis_I_spec.html
+
+header="OggS"
+
+# Codecs
+"BBCD\x00"
+"\x7fFLAC"
+"\x80theora"
+"\x01vorbis"
+"CELT "
+"CMML\x00\x00\x00\x00"
+"\x8bJNG\x0d\x0a\x1a\x0a"
+"\x80kate\x00\x00\x00"
+"OggMIDI\x00"
+"\x8aMNG\x0d\x0a\x1a\x0a"
+"PCM "
+"\x89PNG\x0d\x0a\x1a\x0a"
+"Speex "
+"YUV4MPEG"
+
+# Metadata
+"TITLE="
+"VERSION="
+"ALBUM="
+"TRACKNUMBER="
+"ARTIST="
+"PERFORMER="
+"COPYRIGHT="
+"LICENSE="
+"ORGANIZATION="
+"DESCRIPTION="
+"GENRE="
+"DATE="
+"LOCATION="
+"CONTACT="
+"ISRC="
+
+# webm.dict
+# Element IDs.
+IdAesSettingsCipherMode = "\x47\xE8"
+IdAlphaMode = "\x53\xC0"
+IdAspectRatioType = "\x54\xB3"
+IdAudio = "\xE1"
+IdBitDepth = "\x62\x64"
+IdBitsPerChannel = "\x55\xB2"
+IdBlock = "\xA1"
+IdBlockAddId = "\xEE"
+IdBlockAdditional = "\xA5"
+IdBlockAdditions = "\x75\xA1"
+IdBlockDuration = "\x9B"
+IdBlockGroup = "\xA0"
+IdBlockMore = "\xA6"
+IdBlockVirtual = "\xA2"
+IdCbSubsamplingHorz = "\x55\xB5"
+IdCbSubsamplingVert = "\x55\xB6"
+IdChannels = "\x9F"
+IdChapCountry = "\x43\x7E"
+IdChapLanguage = "\x43\x7C"
+IdChapString = "\x85"
+IdChapterAtom = "\xB6"
+IdChapterDisplay = "\x80"
+IdChapterStringUID = "\x56\x54"
+IdChapterStringUid = "\x56\x54"
+IdChapterTimeEnd = "\x92"
+IdChapterTimeStart = "\x91"
+IdChapterUID = "\x73\xC4"
+IdChapterUid = "\x73\xC4"
+IdChapters = "\x10\x43\xA7\x70"
+IdChromaSitingHorz = "\x55\xB7"
+IdChromaSitingVert = "\x55\xB8"
+IdChromaSubsamplingHorz = "\x55\xB3"
+IdChromaSubsamplingVert = "\x55\xB4"
+IdCluster = "\x1F\x43\xB6\x75"
+IdCodecDelay = "\x56\xAA"
+IdCodecID = "\x86"
+IdCodecName = "\x25\x86\x88"
+IdCodecPrivate = "\x63\xA2"
+IdColour = "\x55\xB0"
+IdContentEncAESSettings = "\x47\xE7"
+IdContentEncAesSettings = "\x47\xE7"
+IdContentEncAlgo = "\x47\xE1"
+IdContentEncKeyId = "\x47\xE2"
+IdContentEncoding = "\x62\x40"
+IdContentEncodingOrder = "\x50\x31"
+IdContentEncodingScope = "\x50\x32"
+IdContentEncodingType = "\x50\x33"
+IdContentEncodings = "\x6D\x80"
+IdContentEncryption = "\x50\x35"
+IdCueBlockNumber = "\x53\x78"
+IdCueClusterPosition = "\xF1"
+IdCueDuration = "\xB2"
+IdCuePoint = "\xBB"
+IdCueRelativePosition = "\xF0"
+IdCueTime = "\xB3"
+IdCueTrack = "\xF7"
+IdCueTrackPositions = "\xB7"
+IdCues = "\x1C\x53\xBB\x6B"
+IdDateUTC = "\x44\x61"
+IdDateUtc = "\x44\x61"
+IdDefaultDuration = "\x23\xE3\x83"
+IdDiscardPadding = "\x75\xA2"
+IdDisplayHeight = "\x54\xBA"
+IdDisplayUnit = "\x54\xB2"
+IdDisplayWidth = "\x54\xB0"
+IdDocType = "\x42\x82"
+IdDocTypeReadVersion = "\x42\x85"
+IdDocTypeVersion = "\x42\x87"
+IdDuration = "\x44\x89"
+IdEBML = "\x1A\x45\xDF\xA3"
+IdEBMLMaxIDLength = "\x42\xF2"
+IdEBMLMaxSizeLength = "\x42\xF3"
+IdEBMLReadVersion = "\x42\xF7"
+IdEBMLVersion = "\x42\x86"
+IdEbml = "\x1A\x45\xDF\xA3"
+IdEbmlMaxIdLength = "\x42\xF2"
+IdEbmlMaxSizeLength = "\x42\xF3"
+IdEbmlReadVersion = "\x42\xF7"
+IdEbmlVersion = "\x42\x86"
+IdEditionEntry = "\x45\xB9"
+IdFileUsedEndTime = "\x46\x62"
+IdFileUsedStartTime = "\x46\x61"
+IdFlagDefault = "\x88"
+IdFlagEnabled = "\xB9"
+IdFlagForced = "\x55\xAA"
+IdFlagInterlaced = "\x9A"
+IdFlagLacing = "\x9C"
+IdFrameRate = "\x23\x83\xE3"
+IdInfo = "\x15\x49\xA9\x66"
+IdLaceNumber = "\xCC"
+IdLanguage = "\x22\xB5\x9C"
+IdLuminanceMax = "\x55\xD9"
+IdLuminanceMin = "\x55\xDA"
+IdMasteringMetadata = "\x55\xD0"
+IdMatrixCoefficients = "\x55\xB1"
+IdMaxCll = "\x55\xBC"
+IdMaxFall = "\x55\xBD"
+IdMuxingApp = "\x4D\x80"
+IdName = "\x53\x6E"
+IdOutputSamplingFrequency = "\x78\xB5"
+IdPixelCropBottom = "\x54\xAA"
+IdPixelCropLeft = "\x54\xCC"
+IdPixelCropRight = "\x54\xDD"
+IdPixelCropTop = "\x54\xBB"
+IdPixelHeight = "\xBA"
+IdPixelWidth = "\xB0"
+IdPrevSize = "\xAB"
+IdPrimaries = "\x55\xBB"
+IdPrimaryBChromaticityX = "\x55\xD5"
+IdPrimaryBChromaticityY = "\x55\xD6"
+IdPrimaryGChromaticityX = "\x55\xD3"
+IdPrimaryGChromaticityY = "\x55\xD4"
+IdPrimaryRChromaticityX = "\x55\xD1"
+IdPrimaryRChromaticityY = "\x55\xD2"
+IdProjection = "\x76\x70"
+IdProjectionPosePitch = "\x76\x74"
+IdProjectionPoseRoll = "\x76\x75"
+IdProjectionPoseYaw = "\x76\x73"
+IdProjectionPrivate = "\x76\x72"
+IdProjectionType = "\x76\x71"
+IdRange = "\x55\xB9"
+IdReferenceBlock = "\xFB"
+IdSamplingFrequency = "\xB5"
+IdSeek = "\x4D\xBB"
+IdSeekHead = "\x11\x4D\x9B\x74"
+IdSeekID = "\x53\xAB"
+IdSeekPosition = "\x53\xAC"
+IdSeekPreRoll = "\x56\xBB"
+IdSegment = "\x18\x53\x80\x67"
+IdSimpleBlock = "\xA3"
+IdSimpleTag = "\x67\xC8"
+IdSliceDuration = "\xCF"
+IdSlices = "\x8E"
+IdStereoMode = "\x53\xB8"
+IdTag = "\x73\x73"
+IdTagBinary = "\x44\x85"
+IdTagDefault = "\x44\x84"
+IdTagLanguage = "\x44\x7A"
+IdTagName = "\x45\xA3"
+IdTagString = "\x44\x87"
+IdTagTrackUid = "\x63\xC5"
+IdTags = "\x12\x54\xC3\x67"
+IdTargetType = "\x63\xCA"
+IdTargetTypeValue = "\x68\xCA"
+IdTargets = "\x63\xC0"
+IdTimeSlice = "\xE8"
+IdTimecode = "\xE7"
+IdTimecodeScale = "\x2A\xD7\xB1"
+IdTitle = "\x7B\xA9"
+IdTrackEntry = "\xAE"
+IdTrackNumber = "\xD7"
+IdTrackType = "\x83"
+IdTrackUID = "\x73\xC5"
+IdTracks = "\x16\x54\xAE\x6B"
+IdTransferCharacteristics = "\x55\xBA"
+IdTrickMasterTrackSegmentUID = "\xC4"
+IdTrickMasterTrackUID = "\xC7"
+IdTrickTrackFlag = "\xC6"
+IdTrickTrackSegmentUID = "\xC1"
+IdTrickTrackUID = "\xC0"
+IdVideo = "\xE0"
+IdVoid = "\xEC"
+IdWhitePointChromaticityX = "\x55\xD7"
+IdWhitePointChromaticityY = "\x55\xD8"
+IdWritingApp = "\x57\x41"
+
+# Interesting sizes.
+SizeUnknown = "\xFF"
+
diff --git a/media/libstagefright/writer_fuzzers/Android.bp b/media/libstagefright/writer_fuzzers/Android.bp
index 224aeb3..f1e504d 100644
--- a/media/libstagefright/writer_fuzzers/Android.bp
+++ b/media/libstagefright/writer_fuzzers/Android.bp
@@ -58,3 +58,59 @@
"WriterFuzzerBase.cpp",
],
}
+
+cc_fuzz {
+ name: "amrnb_writer_fuzzer",
+ defaults: ["writer-fuzzer-defaults"],
+ srcs: [
+ "amr_writer_fuzzer.cpp",
+ ],
+ cflags: [
+ "-DAMRNB",
+ ],
+}
+
+cc_fuzz {
+ name: "amrwb_writer_fuzzer",
+ defaults: ["writer-fuzzer-defaults"],
+ srcs: [
+ "amr_writer_fuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name : "mpeg4_writer_fuzzer",
+ defaults : ["writer-fuzzer-defaults"],
+ srcs : [
+ "mpeg4_writer_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libstagefright_esds",
+ ],
+}
+
+cc_fuzz {
+ name : "ogg_writer_fuzzer",
+ defaults : ["writer-fuzzer-defaults"],
+ srcs : [
+ "ogg_writer_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libogg",
+ ],
+}
+
+cc_fuzz {
+ name : "webm_writer_fuzzer",
+ defaults : ["writer-fuzzer-defaults"],
+ srcs : [
+ "webm_writer_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libstagefright_webm",
+ "libdatasource",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libstagefright",
+ ],
+}
diff --git a/media/libstagefright/writer_fuzzers/README.md b/media/libstagefright/writer_fuzzers/README.md
index 037236a..0d21031 100644
--- a/media/libstagefright/writer_fuzzers/README.md
+++ b/media/libstagefright/writer_fuzzers/README.md
@@ -1,7 +1,11 @@
# Fuzzer for writers
## Table of contents
- [libwriterfuzzerbase](#WriterFuzzerBase)
++ [libwriterfuzzerbase](#WriterFuzzerBase)
++ [Amr Writer](#amrWriterFuzzer)
++ [MPEG4 Writer](#mpeg4WriterFuzzer)
++ [OGG Writer](#oggWriterFuzzer)
++ [WEBM Writer](#webmWriterFuzzer)
# <a name="WriterFuzzerBase"></a> Fuzzer for libwriterfuzzerbase
All the writers have a common API - creating a writer, adding a source for
@@ -40,6 +44,56 @@
This ensures that the plugin tolerates any kind of input (huge,
malformed, etc) and thereby increasing the chance of identifying vulnerabilities.
+# <a name="amrWriterFuzzer"></a> Fuzzer for Amr Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for AMR writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the AMR writer class.
+
+##### Other considerations
+ * Two fuzzer binaries - amrnb_writer_fuzzer and amrwb_writer_fuzzer are generated based on the presence of a flag - 'AMRNB'
+
+# <a name="mpeg4WriterFuzzer"></a> Fuzzer for MPEG4 Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for MPEG4 writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the MPEG4 writer class.
+
+# <a name="oggWriterFuzzer"></a> Fuzzer for OGG Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for OGG writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the OGG writer class.
+
+# <a name="webmWriterFuzzer"></a> Fuzzer for WEBM Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for WEBM writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the WEBM writer class.
+
+## Build
+
+This describes steps to build writer fuzzer binaries.
+
+### Android
+
+`*` = amrnb/amrwb/mpeg4/ogg/webm
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) *_writer_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some media files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/*_writer_fuzzer/*_writer_fuzzer CORPUS_DIR
+```
+
## References:
* http://llvm.org/docs/LibFuzzer.html
diff --git a/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
index 65593e7..844db39 100644
--- a/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
+++ b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
@@ -218,7 +218,7 @@
}
}
-void WriterFuzzerBase::processData(const uint8_t *data, size_t size) {
+void WriterFuzzerBase::initFileWriterAndProcessData(const uint8_t *data, size_t size) {
if (!createOutputFile()) {
return;
}
diff --git a/media/libstagefright/writer_fuzzers/amr_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/amr_writer_fuzzer.cpp
new file mode 100644
index 0000000..bbb6f9f
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/amr_writer_fuzzer.cpp
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * 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 "WriterFuzzerBase.h"
+
+#include <media/stagefright/AMRWriter.h>
+
+using namespace android;
+
+class AmrWriterFuzzer : public WriterFuzzerBase {
+ public:
+ bool createWriter();
+};
+
+bool AmrWriterFuzzer::createWriter() {
+ mWriter = new AMRWriter(mFd);
+ if (!mWriter) {
+ return false;
+ }
+ mFileMeta = new MetaData;
+#ifdef AMRNB
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_NB);
+#else
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_WB);
+#endif
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ AmrWriterFuzzer writerFuzzer;
+ writerFuzzer.initFileWriterAndProcessData(data, size);
+ return 0;
+}
diff --git a/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h b/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
index d819d43..da06463 100644
--- a/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
+++ b/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
@@ -107,7 +107,7 @@
void sendBuffersToWriter(sp<MediaAdapter>& currentTrack, int32_t trackIndex);
- void processData(const uint8_t* data, size_t size);
+ void initFileWriterAndProcessData(const uint8_t* data, size_t size);
protected:
class BufferSource {
diff --git a/media/libstagefright/writer_fuzzers/mpeg4_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/mpeg4_writer_fuzzer.cpp
new file mode 100644
index 0000000..99bd2b6
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/mpeg4_writer_fuzzer.cpp
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * 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 "WriterFuzzerBase.h"
+
+#include <media/stagefright/MPEG4Writer.h>
+
+using namespace android;
+
+class Mpeg4WriterFuzzer : public WriterFuzzerBase {
+ public:
+ bool createWriter();
+};
+
+bool Mpeg4WriterFuzzer::createWriter() {
+ mWriter = new MPEG4Writer(mFd);
+ if (!mWriter) {
+ return false;
+ }
+ mFileMeta = new MetaData;
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_MPEG_4);
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ Mpeg4WriterFuzzer writerFuzzer;
+ writerFuzzer.initFileWriterAndProcessData(data, size);
+ return 0;
+}
diff --git a/media/libstagefright/writer_fuzzers/ogg_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/ogg_writer_fuzzer.cpp
new file mode 100644
index 0000000..ae9c94c
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/ogg_writer_fuzzer.cpp
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * 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 "WriterFuzzerBase.h"
+
+#include <media/stagefright/OggWriter.h>
+
+using namespace android;
+
+class OGGWriterFuzzer : public WriterFuzzerBase {
+ public:
+ bool createWriter();
+};
+
+bool OGGWriterFuzzer::createWriter() {
+ mWriter = new OggWriter(mFd);
+ if (!mWriter) {
+ return false;
+ }
+ mFileMeta = new MetaData;
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_OGG);
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ OGGWriterFuzzer writerFuzzer;
+ writerFuzzer.initFileWriterAndProcessData(data, size);
+ return 0;
+}
diff --git a/media/libstagefright/writer_fuzzers/webm_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/webm_writer_fuzzer.cpp
new file mode 100644
index 0000000..0a91b72
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/webm_writer_fuzzer.cpp
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * 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 "WriterFuzzerBase.h"
+
+#include <webm/WebmWriter.h>
+
+using namespace android;
+
+class WEBMWriterFuzzer : public WriterFuzzerBase {
+ public:
+ bool createWriter();
+};
+
+bool WEBMWriterFuzzer::createWriter() {
+ mWriter = new WebmWriter(mFd);
+ if (!mWriter) {
+ return false;
+ }
+ mFileMeta = new MetaData;
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_WEBM);
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ WEBMWriterFuzzer writerFuzzer;
+ writerFuzzer.initFileWriterAndProcessData(data, size);
+ return 0;
+}
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index b5c67a1..e1634cf 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -21,6 +21,7 @@
#include <gtest/gtest.h>
#include <media/AudioSystem.h>
+#include <media/TypeConverter.h>
#include <system/audio.h>
#include <utils/Log.h>
@@ -68,9 +69,18 @@
ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
for (auto desc : manager.getConfig().getInputDevices()) {
- ASSERT_NE(attachedDevices.end(), attachedDevices.find(desc->type()));
+ if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
+ std::string deviceType;
+ (void)DeviceConverter::toString(desc->type(), deviceType);
+ ADD_FAILURE() << "Input device \"" << deviceType << "\" not found";
+ }
}
for (auto desc : manager.getConfig().getOutputDevices()) {
- ASSERT_NE(attachedDevices.end(), attachedDevices.find(desc->type()));
+ if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
+ std::string deviceType;
+ (void)DeviceConverter::toString(desc->type(), deviceType);
+ ADD_FAILURE() << "Output device \"" << deviceType << "\" not found";
+ }
}
}
+