Loading media/libstagefright/tests/fuzzers/FrameDecoderFuzzer.cpp +51 −48 Original line number Diff line number Diff line Loading @@ -24,61 +24,64 @@ namespace android { #define MAX_MEDIA_BUFFER_SIZE 2048 static const android_pixel_format_t kColorFormats[] = { HAL_PIXEL_FORMAT_RGBA_8888, HAL_PIXEL_FORMAT_RGB_565, HAL_PIXEL_FORMAT_BGRA_8888, HAL_PIXEL_FORMAT_RGBA_1010102, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, /* To cover the default case */ }; static const MediaSource::ReadOptions::SeekMode kSeekModes[] = { MediaSource::ReadOptions::SeekMode::SEEK_PREVIOUS_SYNC, MediaSource::ReadOptions::SeekMode::SEEK_NEXT_SYNC, MediaSource::ReadOptions::SeekMode::SEEK_CLOSEST_SYNC, MediaSource::ReadOptions::SeekMode::SEEK_CLOSEST, MediaSource::ReadOptions::SeekMode::SEEK_FRAME_INDEX, }; static const std::string kComponentNames[] = { "c2.android.avc.decoder", "c2.android.hevc.decoder", "c2.android.vp8.decoder", "c2.android.vp9.decoder", "c2.android.av1.decoder", "c2.android.mpeg4.decoder", "c2.android.h263.decoder", }; // Fuzzer entry point. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Init our wrapper FuzzedDataProvider fdp(data, size); std::string component = fdp.PickValueInArray(kComponentNames); AString componentName(component.c_str()); sp<MetaData> trackMeta = generateMetaData(&fdp, component); sp<IMediaSource> source = sp<IMediaSourceFuzzImpl>::make(&fdp, gMaxMediaBufferSize); 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); sp<FrameDecoder> decoder = nullptr; if (fdp.ConsumeBool()) { decoder = sp<MediaImageDecoder>::make(componentName, trackMeta, source); } else { decoder = new MediaImageDecoder(componentName, trackMeta, source); decoder = sp<VideoFrameDecoder>::make(componentName, trackMeta, source); } while (fdp.remaining_bytes()) { uint8_t switchCase = fdp.ConsumeIntegralInRange<uint8_t>(0, 3); switch (switchCase) { case 0: { int64_t frameTimeUs = fdp.ConsumeIntegral<int64_t>(); int option = fdp.ConsumeIntegral<int>(); int colorFormat = fdp.ConsumeIntegral<int>(); decoder->init(frameTimeUs, option, colorFormat); 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>(); if (decoder.get() && decoder->init(fdp.ConsumeIntegral<uint64_t>() /* frameTimeUs */, fdp.PickValueInArray(kSeekModes) /* option */, fdp.PickValueInArray(kColorFormats) /* colorFormat */) == OK) { auto frameDecoderAPI = fdp.PickValueInArray<const std::function<void()>>({ [&]() { decoder->extractFrame(); }, [&]() { FrameRect rect(fdp.ConsumeIntegral<int32_t>() /* left */, fdp.ConsumeIntegral<int32_t>() /* top */, fdp.ConsumeIntegral<int32_t>() /* right */, fdp.ConsumeIntegral<int32_t>() /* bottom */ ); decoder->extractFrame(&rect); break; } case 3: { sp<MetaData> trackMeta = generateMetaData(&fdp); decoder->getMetadataOnly(trackMeta, /*colorFormat*/ fdp.ConsumeIntegral<int>(), /*thumbnail*/ fdp.ConsumeBool()); break; }, [&]() { FrameDecoder::getMetadataOnly( trackMeta, fdp.PickValueInArray(kColorFormats) /* colorFormat */, fdp.ConsumeBool() /* thumbnail */); }, }); frameDecoderAPI(); } } } generated_mime_types.clear(); return 0; } Loading media/libstagefright/tests/fuzzers/FrameDecoderHelpers.h +89 −58 Original line number Diff line number Diff line Loading @@ -20,17 +20,25 @@ #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; constexpr uint8_t kMinKeyHeight = 32; constexpr uint8_t kMinKeyWidth = 32; constexpr uint16_t kMaxKeyHeight = 2160; constexpr uint16_t kMaxKeyWidth = 3840; size_t gMaxMediaBufferSize = 0; sp<MetaData> generateMetaData(FuzzedDataProvider *fdp) { sp<MetaData> newMeta = new MetaData(); sp<MetaData> generateMetaData(FuzzedDataProvider* fdp, std::string componentName = std::string()) { sp<MetaData> newMeta = sp<MetaData>::make(); // random MIME Type const char *mime_type; const char* mime; if(!componentName.empty()) { auto it = decoderToMediaType.find(componentName); mime = it->second; } else{ size_t index = fdp->ConsumeIntegralInRange<size_t>(0, kMimeTypes.size()); // Let there be a chance of a true random string if (index == kMimeTypes.size()) { Loading @@ -38,51 +46,74 @@ sp<MetaData> generateMetaData(FuzzedDataProvider *fdp) { 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(); mime = mime_cstr.get(); } else { mime = kMimeTypes[index]; } } newMeta->setCString(kKeyMIMEType, mime); auto height = fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyHeight, kMaxKeyHeight); auto width = fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyWidth, kMaxKeyWidth); newMeta->setInt32(kKeyHeight, height); newMeta->setInt32(kKeyWidth, width); gMaxMediaBufferSize = height * width; if (fdp->ConsumeBool()) { newMeta->setInt32(kKeyTileHeight, fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyHeight, height)); newMeta->setInt32(kKeyTileWidth, fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyWidth, width)); newMeta->setInt32(kKeyGridRows, fdp->ConsumeIntegral<uint8_t>()); newMeta->setInt32(kKeyGridCols, fdp->ConsumeIntegral<uint8_t>()); } if (fdp->ConsumeBool()) { newMeta->setInt32(kKeySARHeight, fdp->ConsumeIntegral<uint8_t>()); newMeta->setInt32(kKeySARWidth, fdp->ConsumeIntegral<uint8_t>()); } if (fdp->ConsumeBool()) { newMeta->setInt32(kKeyDisplayHeight, fdp->ConsumeIntegralInRange<uint16_t>(height, UINT16_MAX)); newMeta->setInt32(kKeyDisplayWidth, fdp->ConsumeIntegralInRange<uint16_t>(width, UINT16_MAX)); } if (fdp->ConsumeBool()) { newMeta->setRect(kKeyCropRect, fdp->ConsumeIntegral<int32_t>() /* left */, fdp->ConsumeIntegral<int32_t>() /* top */, fdp->ConsumeIntegral<int32_t>() /* right */, fdp->ConsumeIntegral<int32_t>() /* bottom */); } if (fdp->ConsumeBool()) { newMeta->setInt32(kKeyRotation, fdp->ConsumeIntegralInRange<uint8_t>(0, 3) * 90); } if (fdp->ConsumeBool()) { newMeta->setInt64(kKeyThumbnailTime, fdp->ConsumeIntegral<uint64_t>()); newMeta->setInt32(kKeyThumbnailHeight, fdp->ConsumeIntegral<uint8_t>()); newMeta->setInt32(kKeyThumbnailWidth, fdp->ConsumeIntegral<uint8_t>()); size_t thumbnailSize = fdp->ConsumeIntegral<size_t>(); std::vector<uint8_t> thumbnailData = fdp->ConsumeBytes<uint8_t>(thumbnailSize); if (mime == MEDIA_MIMETYPE_VIDEO_AV1) { newMeta->setData(kKeyThumbnailAV1C, fdp->ConsumeIntegral<int32_t>() /* type */, thumbnailData.data(), thumbnailData.size()); } else { mime_type = kMimeTypes[index]; newMeta->setData(kKeyThumbnailHVCC, fdp->ConsumeIntegral<int32_t>() /* type */, thumbnailData.data(), thumbnailData.size()); } } if (fdp->ConsumeBool()) { size_t profileSize = fdp->ConsumeIntegral<size_t>(); std::vector<uint8_t> profileData = fdp->ConsumeBytes<uint8_t>(profileSize); newMeta->setData(kKeyIccProfile, fdp->ConsumeIntegral<int32_t>() /* type */, profileData.data(), profileData.size()); } 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; } Loading media/libstagefright/tests/fuzzers/IMediaSourceFuzzImpl.h +43 −32 Original line number Diff line number Diff line Loading @@ -19,18 +19,18 @@ #include <media/stagefright/MediaSource.h> #define MAX_FRAMES 5 namespace android { class IMediaSourceFuzzImpl : public IMediaSource { public: IMediaSourceFuzzImpl(FuzzedDataProvider *_fdp, size_t _max_buffer_size) : fdp(_fdp), max_buffer_size(_max_buffer_size) {} IMediaSourceFuzzImpl(FuzzedDataProvider* _fdp, size_t _max_buffer_size) : frames_read(0), fdp(_fdp), min_buffer_size(32 * 32), 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 read(MediaBufferBase**, const MediaSource::ReadOptions*) override; status_t readMultiple(Vector<MediaBufferBase*>*, uint32_t, const MediaSource::ReadOptions*) override; bool supportReadMultiple() override { return true; } Loading @@ -41,9 +41,11 @@ class IMediaSourceFuzzImpl : public IMediaSource { IBinder* onAsBinder() { return nullptr; } private: uint8_t frames_read; FuzzedDataProvider* fdp; std::vector<std::shared_ptr<MediaBufferBase>> buffer_bases; const size_t min_buffer_size; const size_t max_buffer_size; std::vector<uint8_t> buf; }; // This class is simply to expose the destructor Loading @@ -53,32 +55,41 @@ class MediaBufferFuzzImpl : public MediaBuffer { ~MediaBufferFuzzImpl() {} }; status_t IMediaSourceFuzzImpl::read(MediaBufferBase **buffer, const MediaSource::ReadOptions *options) { status_t IMediaSourceFuzzImpl::read(MediaBufferBase** buffer, const MediaSource::ReadOptions*) { Vector<MediaBufferBase*> buffers; status_t ret = readMultiple(&buffers, 1, options); status_t ret = readMultiple(&buffers, 1, nullptr); *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)); status_t IMediaSourceFuzzImpl::readMultiple(Vector<MediaBufferBase*>* buffers, uint32_t, const MediaSource::ReadOptions*) { if (++frames_read == MAX_FRAMES) { auto size = fdp->ConsumeIntegralInRange<size_t>(min_buffer_size, max_buffer_size); buf = fdp->ConsumeBytes<uint8_t>(size); if (buf.size() < size) { buf.resize(size, 0); } MediaBufferBase* mbb = new MediaBufferFuzzImpl(buf.data(), buf.size()); mbb->meta_data().setInt64(kKeyTime, fdp->ConsumeIntegral<uint64_t>()); buffers->push_back(mbb); std::shared_ptr<MediaBufferBase> mbb( new MediaBufferFuzzImpl(buf.data(), buf.size())); return ERROR_END_OF_STREAM; } buffer_bases.push_back(mbb); buffers->push_back(mbb.get()); auto size = fdp->ConsumeIntegralInRange<size_t>(min_buffer_size, max_buffer_size); buf = fdp->ConsumeBytes<uint8_t>(size); if (buf.size() < size) { buf.resize(size, 0); } // STATUS_OK return 0; MediaBufferBase* mbb = new MediaBufferFuzzImpl(buf.data(), buf.size()); mbb->meta_data().setInt64(kKeyTime, fdp->ConsumeIntegral<uint64_t>()); buffers->push_back(mbb); return OK; } } // namespace android Loading media/libstagefright/tests/fuzzers/MediaMimeTypes.h +10 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define FUZZER_MEDIAMIMETYPES_H_ #include <media/stagefright/foundation/MediaDefs.h> #include <unordered_map> namespace android { Loading Loading @@ -80,6 +81,15 @@ static const std::vector<const char*> kMimeTypes { MEDIA_MIMETYPE_DATA_TIMED_ID3 }; static const std::unordered_map<std::string, const char*> decoderToMediaType = { {"c2.android.vp8.decoder", MEDIA_MIMETYPE_VIDEO_VP8}, {"c2.android.vp9.decoder", MEDIA_MIMETYPE_VIDEO_VP9}, {"c2.android.av1.decoder", MEDIA_MIMETYPE_VIDEO_AV1}, {"c2.android.avc.decoder", MEDIA_MIMETYPE_VIDEO_AVC}, {"c2.android.hevc.decoder", MEDIA_MIMETYPE_VIDEO_HEVC}, {"c2.android.mpeg4.decoder", MEDIA_MIMETYPE_VIDEO_MPEG4}, {"c2.android.h263.decoder", MEDIA_MIMETYPE_VIDEO_H263}}; } // namespace android #endif // FUZZER_MEDIAMIMETYPES_H_ media/libstagefright/tests/fuzzers/corpus/0ef67b8a074fed50b8875df345ab2e62175c34c9 0 → 100644 +502 KiB File added.No diff preview for this file type. View file Loading
media/libstagefright/tests/fuzzers/FrameDecoderFuzzer.cpp +51 −48 Original line number Diff line number Diff line Loading @@ -24,61 +24,64 @@ namespace android { #define MAX_MEDIA_BUFFER_SIZE 2048 static const android_pixel_format_t kColorFormats[] = { HAL_PIXEL_FORMAT_RGBA_8888, HAL_PIXEL_FORMAT_RGB_565, HAL_PIXEL_FORMAT_BGRA_8888, HAL_PIXEL_FORMAT_RGBA_1010102, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, /* To cover the default case */ }; static const MediaSource::ReadOptions::SeekMode kSeekModes[] = { MediaSource::ReadOptions::SeekMode::SEEK_PREVIOUS_SYNC, MediaSource::ReadOptions::SeekMode::SEEK_NEXT_SYNC, MediaSource::ReadOptions::SeekMode::SEEK_CLOSEST_SYNC, MediaSource::ReadOptions::SeekMode::SEEK_CLOSEST, MediaSource::ReadOptions::SeekMode::SEEK_FRAME_INDEX, }; static const std::string kComponentNames[] = { "c2.android.avc.decoder", "c2.android.hevc.decoder", "c2.android.vp8.decoder", "c2.android.vp9.decoder", "c2.android.av1.decoder", "c2.android.mpeg4.decoder", "c2.android.h263.decoder", }; // Fuzzer entry point. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Init our wrapper FuzzedDataProvider fdp(data, size); std::string component = fdp.PickValueInArray(kComponentNames); AString componentName(component.c_str()); sp<MetaData> trackMeta = generateMetaData(&fdp, component); sp<IMediaSource> source = sp<IMediaSourceFuzzImpl>::make(&fdp, gMaxMediaBufferSize); 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); sp<FrameDecoder> decoder = nullptr; if (fdp.ConsumeBool()) { decoder = sp<MediaImageDecoder>::make(componentName, trackMeta, source); } else { decoder = new MediaImageDecoder(componentName, trackMeta, source); decoder = sp<VideoFrameDecoder>::make(componentName, trackMeta, source); } while (fdp.remaining_bytes()) { uint8_t switchCase = fdp.ConsumeIntegralInRange<uint8_t>(0, 3); switch (switchCase) { case 0: { int64_t frameTimeUs = fdp.ConsumeIntegral<int64_t>(); int option = fdp.ConsumeIntegral<int>(); int colorFormat = fdp.ConsumeIntegral<int>(); decoder->init(frameTimeUs, option, colorFormat); 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>(); if (decoder.get() && decoder->init(fdp.ConsumeIntegral<uint64_t>() /* frameTimeUs */, fdp.PickValueInArray(kSeekModes) /* option */, fdp.PickValueInArray(kColorFormats) /* colorFormat */) == OK) { auto frameDecoderAPI = fdp.PickValueInArray<const std::function<void()>>({ [&]() { decoder->extractFrame(); }, [&]() { FrameRect rect(fdp.ConsumeIntegral<int32_t>() /* left */, fdp.ConsumeIntegral<int32_t>() /* top */, fdp.ConsumeIntegral<int32_t>() /* right */, fdp.ConsumeIntegral<int32_t>() /* bottom */ ); decoder->extractFrame(&rect); break; } case 3: { sp<MetaData> trackMeta = generateMetaData(&fdp); decoder->getMetadataOnly(trackMeta, /*colorFormat*/ fdp.ConsumeIntegral<int>(), /*thumbnail*/ fdp.ConsumeBool()); break; }, [&]() { FrameDecoder::getMetadataOnly( trackMeta, fdp.PickValueInArray(kColorFormats) /* colorFormat */, fdp.ConsumeBool() /* thumbnail */); }, }); frameDecoderAPI(); } } } generated_mime_types.clear(); return 0; } Loading
media/libstagefright/tests/fuzzers/FrameDecoderHelpers.h +89 −58 Original line number Diff line number Diff line Loading @@ -20,17 +20,25 @@ #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; constexpr uint8_t kMinKeyHeight = 32; constexpr uint8_t kMinKeyWidth = 32; constexpr uint16_t kMaxKeyHeight = 2160; constexpr uint16_t kMaxKeyWidth = 3840; size_t gMaxMediaBufferSize = 0; sp<MetaData> generateMetaData(FuzzedDataProvider *fdp) { sp<MetaData> newMeta = new MetaData(); sp<MetaData> generateMetaData(FuzzedDataProvider* fdp, std::string componentName = std::string()) { sp<MetaData> newMeta = sp<MetaData>::make(); // random MIME Type const char *mime_type; const char* mime; if(!componentName.empty()) { auto it = decoderToMediaType.find(componentName); mime = it->second; } else{ size_t index = fdp->ConsumeIntegralInRange<size_t>(0, kMimeTypes.size()); // Let there be a chance of a true random string if (index == kMimeTypes.size()) { Loading @@ -38,51 +46,74 @@ sp<MetaData> generateMetaData(FuzzedDataProvider *fdp) { 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(); mime = mime_cstr.get(); } else { mime = kMimeTypes[index]; } } newMeta->setCString(kKeyMIMEType, mime); auto height = fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyHeight, kMaxKeyHeight); auto width = fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyWidth, kMaxKeyWidth); newMeta->setInt32(kKeyHeight, height); newMeta->setInt32(kKeyWidth, width); gMaxMediaBufferSize = height * width; if (fdp->ConsumeBool()) { newMeta->setInt32(kKeyTileHeight, fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyHeight, height)); newMeta->setInt32(kKeyTileWidth, fdp->ConsumeIntegralInRange<uint16_t>(kMinKeyWidth, width)); newMeta->setInt32(kKeyGridRows, fdp->ConsumeIntegral<uint8_t>()); newMeta->setInt32(kKeyGridCols, fdp->ConsumeIntegral<uint8_t>()); } if (fdp->ConsumeBool()) { newMeta->setInt32(kKeySARHeight, fdp->ConsumeIntegral<uint8_t>()); newMeta->setInt32(kKeySARWidth, fdp->ConsumeIntegral<uint8_t>()); } if (fdp->ConsumeBool()) { newMeta->setInt32(kKeyDisplayHeight, fdp->ConsumeIntegralInRange<uint16_t>(height, UINT16_MAX)); newMeta->setInt32(kKeyDisplayWidth, fdp->ConsumeIntegralInRange<uint16_t>(width, UINT16_MAX)); } if (fdp->ConsumeBool()) { newMeta->setRect(kKeyCropRect, fdp->ConsumeIntegral<int32_t>() /* left */, fdp->ConsumeIntegral<int32_t>() /* top */, fdp->ConsumeIntegral<int32_t>() /* right */, fdp->ConsumeIntegral<int32_t>() /* bottom */); } if (fdp->ConsumeBool()) { newMeta->setInt32(kKeyRotation, fdp->ConsumeIntegralInRange<uint8_t>(0, 3) * 90); } if (fdp->ConsumeBool()) { newMeta->setInt64(kKeyThumbnailTime, fdp->ConsumeIntegral<uint64_t>()); newMeta->setInt32(kKeyThumbnailHeight, fdp->ConsumeIntegral<uint8_t>()); newMeta->setInt32(kKeyThumbnailWidth, fdp->ConsumeIntegral<uint8_t>()); size_t thumbnailSize = fdp->ConsumeIntegral<size_t>(); std::vector<uint8_t> thumbnailData = fdp->ConsumeBytes<uint8_t>(thumbnailSize); if (mime == MEDIA_MIMETYPE_VIDEO_AV1) { newMeta->setData(kKeyThumbnailAV1C, fdp->ConsumeIntegral<int32_t>() /* type */, thumbnailData.data(), thumbnailData.size()); } else { mime_type = kMimeTypes[index]; newMeta->setData(kKeyThumbnailHVCC, fdp->ConsumeIntegral<int32_t>() /* type */, thumbnailData.data(), thumbnailData.size()); } } if (fdp->ConsumeBool()) { size_t profileSize = fdp->ConsumeIntegral<size_t>(); std::vector<uint8_t> profileData = fdp->ConsumeBytes<uint8_t>(profileSize); newMeta->setData(kKeyIccProfile, fdp->ConsumeIntegral<int32_t>() /* type */, profileData.data(), profileData.size()); } 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; } Loading
media/libstagefright/tests/fuzzers/IMediaSourceFuzzImpl.h +43 −32 Original line number Diff line number Diff line Loading @@ -19,18 +19,18 @@ #include <media/stagefright/MediaSource.h> #define MAX_FRAMES 5 namespace android { class IMediaSourceFuzzImpl : public IMediaSource { public: IMediaSourceFuzzImpl(FuzzedDataProvider *_fdp, size_t _max_buffer_size) : fdp(_fdp), max_buffer_size(_max_buffer_size) {} IMediaSourceFuzzImpl(FuzzedDataProvider* _fdp, size_t _max_buffer_size) : frames_read(0), fdp(_fdp), min_buffer_size(32 * 32), 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 read(MediaBufferBase**, const MediaSource::ReadOptions*) override; status_t readMultiple(Vector<MediaBufferBase*>*, uint32_t, const MediaSource::ReadOptions*) override; bool supportReadMultiple() override { return true; } Loading @@ -41,9 +41,11 @@ class IMediaSourceFuzzImpl : public IMediaSource { IBinder* onAsBinder() { return nullptr; } private: uint8_t frames_read; FuzzedDataProvider* fdp; std::vector<std::shared_ptr<MediaBufferBase>> buffer_bases; const size_t min_buffer_size; const size_t max_buffer_size; std::vector<uint8_t> buf; }; // This class is simply to expose the destructor Loading @@ -53,32 +55,41 @@ class MediaBufferFuzzImpl : public MediaBuffer { ~MediaBufferFuzzImpl() {} }; status_t IMediaSourceFuzzImpl::read(MediaBufferBase **buffer, const MediaSource::ReadOptions *options) { status_t IMediaSourceFuzzImpl::read(MediaBufferBase** buffer, const MediaSource::ReadOptions*) { Vector<MediaBufferBase*> buffers; status_t ret = readMultiple(&buffers, 1, options); status_t ret = readMultiple(&buffers, 1, nullptr); *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)); status_t IMediaSourceFuzzImpl::readMultiple(Vector<MediaBufferBase*>* buffers, uint32_t, const MediaSource::ReadOptions*) { if (++frames_read == MAX_FRAMES) { auto size = fdp->ConsumeIntegralInRange<size_t>(min_buffer_size, max_buffer_size); buf = fdp->ConsumeBytes<uint8_t>(size); if (buf.size() < size) { buf.resize(size, 0); } MediaBufferBase* mbb = new MediaBufferFuzzImpl(buf.data(), buf.size()); mbb->meta_data().setInt64(kKeyTime, fdp->ConsumeIntegral<uint64_t>()); buffers->push_back(mbb); std::shared_ptr<MediaBufferBase> mbb( new MediaBufferFuzzImpl(buf.data(), buf.size())); return ERROR_END_OF_STREAM; } buffer_bases.push_back(mbb); buffers->push_back(mbb.get()); auto size = fdp->ConsumeIntegralInRange<size_t>(min_buffer_size, max_buffer_size); buf = fdp->ConsumeBytes<uint8_t>(size); if (buf.size() < size) { buf.resize(size, 0); } // STATUS_OK return 0; MediaBufferBase* mbb = new MediaBufferFuzzImpl(buf.data(), buf.size()); mbb->meta_data().setInt64(kKeyTime, fdp->ConsumeIntegral<uint64_t>()); buffers->push_back(mbb); return OK; } } // namespace android Loading
media/libstagefright/tests/fuzzers/MediaMimeTypes.h +10 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define FUZZER_MEDIAMIMETYPES_H_ #include <media/stagefright/foundation/MediaDefs.h> #include <unordered_map> namespace android { Loading Loading @@ -80,6 +81,15 @@ static const std::vector<const char*> kMimeTypes { MEDIA_MIMETYPE_DATA_TIMED_ID3 }; static const std::unordered_map<std::string, const char*> decoderToMediaType = { {"c2.android.vp8.decoder", MEDIA_MIMETYPE_VIDEO_VP8}, {"c2.android.vp9.decoder", MEDIA_MIMETYPE_VIDEO_VP9}, {"c2.android.av1.decoder", MEDIA_MIMETYPE_VIDEO_AV1}, {"c2.android.avc.decoder", MEDIA_MIMETYPE_VIDEO_AVC}, {"c2.android.hevc.decoder", MEDIA_MIMETYPE_VIDEO_HEVC}, {"c2.android.mpeg4.decoder", MEDIA_MIMETYPE_VIDEO_MPEG4}, {"c2.android.h263.decoder", MEDIA_MIMETYPE_VIDEO_H263}}; } // namespace android #endif // FUZZER_MEDIAMIMETYPES_H_
media/libstagefright/tests/fuzzers/corpus/0ef67b8a074fed50b8875df345ab2e62175c34c9 0 → 100644 +502 KiB File added.No diff preview for this file type. View file