Loading media/libstagefright/rtsp/fuzzer/Android.bp 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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. */ cc_defaults { name: "libstagefright_rtsp_fuzzer_defaults", shared_libs: [ "liblog", "libmedia", "libutils", "libstagefright_foundation", ], static_libs: [ "libdatasource", "libstagefright_rtsp", ], header_libs: [ "libstagefright_rtsp_headers", ], fuzz_config:{ cc: [ "android-media-fuzzing-reports@google.com", ], componentid: 155276, }, } cc_fuzz { name: "sdploader_fuzzer", srcs: [ "sdploader_fuzzer.cpp", ], defaults: [ "libstagefright_rtsp_fuzzer_defaults", ] } cc_fuzz { name: "rtp_writer_fuzzer", srcs: [ "rtp_writer_fuzzer.cpp", ], defaults: [ "libstagefright_rtsp_fuzzer_defaults", ], shared_libs:[ "libandroid_net", "libbase", "libstagefright", "libcutils", ], } media/libstagefright/rtsp/fuzzer/README.md 0 → 100644 +64 −0 Original line number Diff line number Diff line # Fuzzers for libstagefright_rtsp ## Table of contents + [sdploader_fuzzer](#SDPLoader) + [rtp_writer_fuzzer](#ARTPWriter) # <a name="SDPLoader"></a> Fuzzer for SDPLoader SDPLoader supports the following parameters: 1. Flag (parameter name: "flags") 2. URL (parameter name: "url") 3. Header (parameter name: "headers") | Parameter| Valid Values| Configured Value| |------------- |-------------| ----- | |`flags`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`url`| `String` |Value obtained from FuzzedDataProvider| |`headers`| `String` |Value obtained from FuzzedDataProvider| #### Steps to run 1. Build the fuzzer ``` $ mm -j$(nproc) sdploader_fuzzer ``` 2. Run on device ``` $ adb sync data $ adb shell /data/fuzz/arm64/sdploader_fuzzer/sdploader_fuzzer ``` # <a name="ARTPWriter"></a> Fuzzer for ARTPWriter ARTPWriter supports the following parameters: 1. File descriptor (parameter name: "fd") 2. Local Ip (parameter name: "localIp") 3. Local Port (parameter name: "localPort") 4. Remote Ip (parameter name: "remoteIp") 5. Remote Port (parameter name: "remotePort") 6. Sequence No (parameter name: "seqNo") 7. OpponentID (parameter name: "opponentID") 8. Bit Rate (parameter name: "bitrate") 9. kKeyMIMETypeArray (parameter name: "mimeType") | Parameter| Valid Values| Configured Value| |------------- |-------------| ----- | |`localIp`| `String` |Value obtained from FuzzedDataProvider| |`localPort`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`remoteIp`| `String` |Value obtained from FuzzedDataProvider| |`remotePort`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`seqNo`| `0` to `10000000` |Value obtained from FuzzedDataProvider| |`opponentID`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`bitrate`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`mimeType`| 0. `MEDIA_MIMETYPE_VIDEO_AVC`<br> 1. `MEDIA_MIMETYPE_VIDEO_HEVC`<br> 2. `MEDIA_MIMETYPE_VIDEO_H263`<br> 3. `MEDIA_MIMETYPE_AUDIO_AMR_NB`<br> 4. `MEDIA_MIMETYPE_AUDIO_AMR_WB`|Value obtained from FuzzedDataProvider| #### Steps to run 1. Build the fuzzer ``` $ mm -j$(nproc) rtp_writer_fuzzer ``` 2. Run on device ``` $ adb sync data $ adb shell /data/fuzz/arm64/rtp_writer_fuzzer/rtp_writer_fuzzer ``` media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp 0 → 100644 +184 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 <fuzzer/FuzzedDataProvider.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/rtsp/ARTPWriter.h> constexpr int32_t kMinSize = 0; constexpr int32_t kMaxSize = 65536; constexpr int32_t kMaxTime = 1000; constexpr int32_t kMaxBytes = 128; constexpr int32_t kAMRNBFrameSizes[] = {13, 14, 16, 18, 20, 21, 27, 32}; constexpr int32_t kAMRWBFrameSizes[] = {18, 24, 33, 37, 41, 47, 51, 59, 61}; constexpr int32_t kAMRIndexOffset = 8; using namespace android; const char* kKeyMimeTypeArray[] = {MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_HEVC, MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB}; struct TestMediaSource : public MediaSource { public: TestMediaSource(FuzzedDataProvider& mFdp) : mTestMetaData(new MetaData) { int32_t vectorSize = 0; mAllowRead = mFdp.ConsumeBool(); mKeySps = mFdp.ConsumeIntegral<int32_t>(); mKeyVps = mFdp.ConsumeIntegral<int32_t>(); mKeyPps = mFdp.ConsumeIntegral<int32_t>(); mKeyTime = mFdp.ConsumeIntegralInRange<int64_t>(kMinSize, kMaxTime); mMimeType = mFdp.PickValueInArray(kKeyMimeTypeArray); mTestMetaData->setCString(kKeyMIMEType, mMimeType); if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_NB) { int32_t index = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRNBFrameSizes) - 1); vectorSize = kAMRNBFrameSizes[index]; mData.push_back(kAMRIndexOffset * index); } else if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB) { int32_t index = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRWBFrameSizes) - 1); vectorSize = kAMRWBFrameSizes[index]; mData.push_back(kAMRIndexOffset * index); } else if (mMimeType == MEDIA_MIMETYPE_VIDEO_H263) { // Required format for H263 media data mData.push_back(0); mData.push_back(0); vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize); } else { vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize); } for (size_t idx = mData.size(); idx < vectorSize; ++idx) { mData.push_back(mFdp.ConsumeIntegral<uint8_t>()); } } virtual status_t start(MetaData* /*params*/) { return OK; } virtual status_t stop() { return OK; } virtual sp<MetaData> getFormat() { return mTestMetaData; } virtual status_t read(MediaBufferBase** buffer, const ReadOptions* /*options*/) { if (!mAllowRead) { return -1; } *buffer = new MediaBuffer(mData.data() /*data*/, mData.size() /*size*/); if (mKeySps) { (*buffer)->meta_data().setInt32(kKeySps, mKeySps); } if (mKeyVps) { (*buffer)->meta_data().setInt32(kKeyVps, mKeyVps); } if (mKeyPps) { (*buffer)->meta_data().setInt32(kKeyPps, mKeyPps); } (*buffer)->meta_data().setInt64(kKeyTime, mKeyTime); return OK; } private: int32_t mKeySps; int32_t mKeyVps; int32_t mKeyPps; int64_t mKeyTime; bool mAllowRead; const char* mMimeType; sp<MetaData> mTestMetaData; std::vector<uint8_t> mData; }; class ARTPWriterFuzzer { public: ARTPWriterFuzzer(const uint8_t* data, size_t size) : mDataSourceFd(memfd_create("InputFile", MFD_ALLOW_SEALING)), mFdp(data, size) {} ~ARTPWriterFuzzer() { close(mDataSourceFd); } void process(); private: void createARTPWriter(); const int32_t mDataSourceFd; FuzzedDataProvider mFdp; sp<ARTPWriter> mArtpWriter; }; void ARTPWriterFuzzer::createARTPWriter() { String8 localIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()); String8 remoteIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()); mArtpWriter = sp<ARTPWriter>::make( mDataSourceFd, localIp, mFdp.ConsumeIntegral<uint16_t>() /* localPort */, remoteIp, mFdp.ConsumeIntegral<uint16_t>() /* remotePort */, mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize) /* seqNo */); } void ARTPWriterFuzzer::process() { if (mFdp.ConsumeBool()) { mArtpWriter = sp<ARTPWriter>::make(mDataSourceFd); if (mArtpWriter->getSequenceNum() > kMaxSize) { createARTPWriter(); } } else { createARTPWriter(); } mArtpWriter->addSource(sp<TestMediaSource>::make(mFdp) /* source */); while (mFdp.remaining_bytes()) { auto invokeRTPWriterFuzzer = mFdp.PickValueInArray<const std::function<void()>>({ [&]() { sp<MetaData> metaData = sp<MetaData>::make(); if (mFdp.ConsumeBool()) { metaData->setInt32(kKeySelfID, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyPayloadType, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyRtpExtMap, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyRtpCvoDegrees, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyRtpDscp, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt64(kKeySocketNetwork, mFdp.ConsumeIntegral<int64_t>()); } mArtpWriter->start(metaData.get() /*param*/); }, [&]() { mArtpWriter->setTMMBNInfo(mFdp.ConsumeIntegral<uint32_t>() /* opponentID */, mFdp.ConsumeIntegral<uint32_t>() /* bitrate */); }, [&]() { mArtpWriter->stop(); }, [&]() { mArtpWriter->updateCVODegrees(mFdp.ConsumeIntegral<int32_t>() /* cvoDegrees */); }, [&]() { mArtpWriter->updatePayloadType( mFdp.ConsumeIntegral<int32_t>() /* payloadType */); }, }); invokeRTPWriterFuzzer(); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ARTPWriterFuzzer artpWriterFuzzer(data, size); artpWriterFuzzer.process(); return 0; } media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 <datasource/HTTPBase.h> #include <fuzzer/FuzzedDataProvider.h> #include <media/MediaHTTPConnection.h> #include <media/MediaHTTPService.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/rtsp/SDPLoader.h> using namespace android; constexpr int32_t kMinCapacity = 0; constexpr int32_t kMaxCapacity = 1000; constexpr int32_t kMaxStringLength = 20; constexpr int32_t kMaxBytes = 128; enum { kWhatLoad = 'load' }; struct FuzzAHandler : public AHandler { public: FuzzAHandler(std::function<void()> signalEosFunction) : mSignalEosFunction(signalEosFunction) {} protected: void onMessageReceived(const sp<AMessage>& msg) override { switch (msg->what()) { case kWhatLoad: { mSignalEosFunction(); break; } } return; } private: std::function<void()> mSignalEosFunction; }; struct FuzzMediaHTTPConnection : public MediaHTTPConnection { public: FuzzMediaHTTPConnection(FuzzedDataProvider* fdp) : mFdp(fdp) { mSize = mFdp->ConsumeIntegralInRange(kMinCapacity, kMaxCapacity); mData = mFdp->ConsumeBytes<uint8_t>(mSize); mSize = mData.size(); } virtual bool connect(const char* /* uri */, const KeyedVector<String8, String8>* /* headers */) { return mFdp->ConsumeBool(); } virtual void disconnect() { return; } virtual ssize_t readAt(off64_t offset, void* data, size_t size) { if (size <= mSize - offset) { data = mData.data() + offset; return size; } else { data = nullptr; return 0; } } virtual off64_t getSize() { return mSize; } virtual status_t getMIMEType(String8* /*mimeType*/) {return mFdp->ConsumeIntegral<status_t>();} virtual status_t getUri(String8* /*uri*/) {return mFdp->ConsumeIntegral<status_t>();} private: FuzzedDataProvider* mFdp = nullptr; std::vector<uint8_t> mData; size_t mSize = 0; }; struct FuzzMediaHTTPService : public MediaHTTPService { public: FuzzMediaHTTPService(FuzzedDataProvider* fdp) : mFdp(fdp) {} virtual sp<MediaHTTPConnection> makeHTTPConnection() { mediaHTTPConnection = sp<FuzzMediaHTTPConnection>::make(mFdp); return mediaHTTPConnection; } private: sp<FuzzMediaHTTPConnection> mediaHTTPConnection = nullptr; FuzzedDataProvider* mFdp = nullptr; }; class SDPLoaderFuzzer { public: SDPLoaderFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {} void process(); private: void signalEos(); bool mEosReached = false; std::mutex mMsgPostCompleteMutex; std::condition_variable mConditionalVariable; FuzzedDataProvider mFdp; }; void SDPLoaderFuzzer::signalEos() { mEosReached = true; mConditionalVariable.notify_one(); return; } void SDPLoaderFuzzer::process() { sp<FuzzAHandler> handler = sp<FuzzAHandler>::make(std::bind(&SDPLoaderFuzzer::signalEos, this)); sp<ALooper> looper = sp<ALooper>::make(); looper->start(); looper->registerHandler(handler); const sp<AMessage> notify = sp<AMessage>::make(kWhatLoad, handler); sp<SDPLoader> sdpLoader = sp<SDPLoader>::make(notify, mFdp.ConsumeIntegral<uint32_t>() /* flags */, sp<FuzzMediaHTTPService>::make(&mFdp) /* httpService */); KeyedVector<String8, String8> headers; for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange<size_t>(kMinCapacity, kMaxCapacity); ++idx) { headers.add(String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* key */, String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* value */); } sdpLoader->load(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* url */, &headers); std::unique_lock waitForMsgPostComplete(mMsgPostCompleteMutex); mConditionalVariable.wait(waitForMsgPostComplete, [this] { return mEosReached; }); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { SDPLoaderFuzzer sdpLoaderFuzzer(data, size); sdpLoaderFuzzer.process(); return 0; } Loading
media/libstagefright/rtsp/fuzzer/Android.bp 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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. */ cc_defaults { name: "libstagefright_rtsp_fuzzer_defaults", shared_libs: [ "liblog", "libmedia", "libutils", "libstagefright_foundation", ], static_libs: [ "libdatasource", "libstagefright_rtsp", ], header_libs: [ "libstagefright_rtsp_headers", ], fuzz_config:{ cc: [ "android-media-fuzzing-reports@google.com", ], componentid: 155276, }, } cc_fuzz { name: "sdploader_fuzzer", srcs: [ "sdploader_fuzzer.cpp", ], defaults: [ "libstagefright_rtsp_fuzzer_defaults", ] } cc_fuzz { name: "rtp_writer_fuzzer", srcs: [ "rtp_writer_fuzzer.cpp", ], defaults: [ "libstagefright_rtsp_fuzzer_defaults", ], shared_libs:[ "libandroid_net", "libbase", "libstagefright", "libcutils", ], }
media/libstagefright/rtsp/fuzzer/README.md 0 → 100644 +64 −0 Original line number Diff line number Diff line # Fuzzers for libstagefright_rtsp ## Table of contents + [sdploader_fuzzer](#SDPLoader) + [rtp_writer_fuzzer](#ARTPWriter) # <a name="SDPLoader"></a> Fuzzer for SDPLoader SDPLoader supports the following parameters: 1. Flag (parameter name: "flags") 2. URL (parameter name: "url") 3. Header (parameter name: "headers") | Parameter| Valid Values| Configured Value| |------------- |-------------| ----- | |`flags`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`url`| `String` |Value obtained from FuzzedDataProvider| |`headers`| `String` |Value obtained from FuzzedDataProvider| #### Steps to run 1. Build the fuzzer ``` $ mm -j$(nproc) sdploader_fuzzer ``` 2. Run on device ``` $ adb sync data $ adb shell /data/fuzz/arm64/sdploader_fuzzer/sdploader_fuzzer ``` # <a name="ARTPWriter"></a> Fuzzer for ARTPWriter ARTPWriter supports the following parameters: 1. File descriptor (parameter name: "fd") 2. Local Ip (parameter name: "localIp") 3. Local Port (parameter name: "localPort") 4. Remote Ip (parameter name: "remoteIp") 5. Remote Port (parameter name: "remotePort") 6. Sequence No (parameter name: "seqNo") 7. OpponentID (parameter name: "opponentID") 8. Bit Rate (parameter name: "bitrate") 9. kKeyMIMETypeArray (parameter name: "mimeType") | Parameter| Valid Values| Configured Value| |------------- |-------------| ----- | |`localIp`| `String` |Value obtained from FuzzedDataProvider| |`localPort`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`remoteIp`| `String` |Value obtained from FuzzedDataProvider| |`remotePort`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`seqNo`| `0` to `10000000` |Value obtained from FuzzedDataProvider| |`opponentID`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`bitrate`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider| |`mimeType`| 0. `MEDIA_MIMETYPE_VIDEO_AVC`<br> 1. `MEDIA_MIMETYPE_VIDEO_HEVC`<br> 2. `MEDIA_MIMETYPE_VIDEO_H263`<br> 3. `MEDIA_MIMETYPE_AUDIO_AMR_NB`<br> 4. `MEDIA_MIMETYPE_AUDIO_AMR_WB`|Value obtained from FuzzedDataProvider| #### Steps to run 1. Build the fuzzer ``` $ mm -j$(nproc) rtp_writer_fuzzer ``` 2. Run on device ``` $ adb sync data $ adb shell /data/fuzz/arm64/rtp_writer_fuzzer/rtp_writer_fuzzer ```
media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp 0 → 100644 +184 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 <fuzzer/FuzzedDataProvider.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/rtsp/ARTPWriter.h> constexpr int32_t kMinSize = 0; constexpr int32_t kMaxSize = 65536; constexpr int32_t kMaxTime = 1000; constexpr int32_t kMaxBytes = 128; constexpr int32_t kAMRNBFrameSizes[] = {13, 14, 16, 18, 20, 21, 27, 32}; constexpr int32_t kAMRWBFrameSizes[] = {18, 24, 33, 37, 41, 47, 51, 59, 61}; constexpr int32_t kAMRIndexOffset = 8; using namespace android; const char* kKeyMimeTypeArray[] = {MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_HEVC, MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB}; struct TestMediaSource : public MediaSource { public: TestMediaSource(FuzzedDataProvider& mFdp) : mTestMetaData(new MetaData) { int32_t vectorSize = 0; mAllowRead = mFdp.ConsumeBool(); mKeySps = mFdp.ConsumeIntegral<int32_t>(); mKeyVps = mFdp.ConsumeIntegral<int32_t>(); mKeyPps = mFdp.ConsumeIntegral<int32_t>(); mKeyTime = mFdp.ConsumeIntegralInRange<int64_t>(kMinSize, kMaxTime); mMimeType = mFdp.PickValueInArray(kKeyMimeTypeArray); mTestMetaData->setCString(kKeyMIMEType, mMimeType); if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_NB) { int32_t index = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRNBFrameSizes) - 1); vectorSize = kAMRNBFrameSizes[index]; mData.push_back(kAMRIndexOffset * index); } else if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB) { int32_t index = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRWBFrameSizes) - 1); vectorSize = kAMRWBFrameSizes[index]; mData.push_back(kAMRIndexOffset * index); } else if (mMimeType == MEDIA_MIMETYPE_VIDEO_H263) { // Required format for H263 media data mData.push_back(0); mData.push_back(0); vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize); } else { vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize); } for (size_t idx = mData.size(); idx < vectorSize; ++idx) { mData.push_back(mFdp.ConsumeIntegral<uint8_t>()); } } virtual status_t start(MetaData* /*params*/) { return OK; } virtual status_t stop() { return OK; } virtual sp<MetaData> getFormat() { return mTestMetaData; } virtual status_t read(MediaBufferBase** buffer, const ReadOptions* /*options*/) { if (!mAllowRead) { return -1; } *buffer = new MediaBuffer(mData.data() /*data*/, mData.size() /*size*/); if (mKeySps) { (*buffer)->meta_data().setInt32(kKeySps, mKeySps); } if (mKeyVps) { (*buffer)->meta_data().setInt32(kKeyVps, mKeyVps); } if (mKeyPps) { (*buffer)->meta_data().setInt32(kKeyPps, mKeyPps); } (*buffer)->meta_data().setInt64(kKeyTime, mKeyTime); return OK; } private: int32_t mKeySps; int32_t mKeyVps; int32_t mKeyPps; int64_t mKeyTime; bool mAllowRead; const char* mMimeType; sp<MetaData> mTestMetaData; std::vector<uint8_t> mData; }; class ARTPWriterFuzzer { public: ARTPWriterFuzzer(const uint8_t* data, size_t size) : mDataSourceFd(memfd_create("InputFile", MFD_ALLOW_SEALING)), mFdp(data, size) {} ~ARTPWriterFuzzer() { close(mDataSourceFd); } void process(); private: void createARTPWriter(); const int32_t mDataSourceFd; FuzzedDataProvider mFdp; sp<ARTPWriter> mArtpWriter; }; void ARTPWriterFuzzer::createARTPWriter() { String8 localIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()); String8 remoteIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()); mArtpWriter = sp<ARTPWriter>::make( mDataSourceFd, localIp, mFdp.ConsumeIntegral<uint16_t>() /* localPort */, remoteIp, mFdp.ConsumeIntegral<uint16_t>() /* remotePort */, mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize) /* seqNo */); } void ARTPWriterFuzzer::process() { if (mFdp.ConsumeBool()) { mArtpWriter = sp<ARTPWriter>::make(mDataSourceFd); if (mArtpWriter->getSequenceNum() > kMaxSize) { createARTPWriter(); } } else { createARTPWriter(); } mArtpWriter->addSource(sp<TestMediaSource>::make(mFdp) /* source */); while (mFdp.remaining_bytes()) { auto invokeRTPWriterFuzzer = mFdp.PickValueInArray<const std::function<void()>>({ [&]() { sp<MetaData> metaData = sp<MetaData>::make(); if (mFdp.ConsumeBool()) { metaData->setInt32(kKeySelfID, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyPayloadType, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyRtpExtMap, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyRtpCvoDegrees, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt32(kKeyRtpDscp, mFdp.ConsumeIntegral<int32_t>()); } if (mFdp.ConsumeBool()) { metaData->setInt64(kKeySocketNetwork, mFdp.ConsumeIntegral<int64_t>()); } mArtpWriter->start(metaData.get() /*param*/); }, [&]() { mArtpWriter->setTMMBNInfo(mFdp.ConsumeIntegral<uint32_t>() /* opponentID */, mFdp.ConsumeIntegral<uint32_t>() /* bitrate */); }, [&]() { mArtpWriter->stop(); }, [&]() { mArtpWriter->updateCVODegrees(mFdp.ConsumeIntegral<int32_t>() /* cvoDegrees */); }, [&]() { mArtpWriter->updatePayloadType( mFdp.ConsumeIntegral<int32_t>() /* payloadType */); }, }); invokeRTPWriterFuzzer(); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ARTPWriterFuzzer artpWriterFuzzer(data, size); artpWriterFuzzer.process(); return 0; }
media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 <datasource/HTTPBase.h> #include <fuzzer/FuzzedDataProvider.h> #include <media/MediaHTTPConnection.h> #include <media/MediaHTTPService.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/rtsp/SDPLoader.h> using namespace android; constexpr int32_t kMinCapacity = 0; constexpr int32_t kMaxCapacity = 1000; constexpr int32_t kMaxStringLength = 20; constexpr int32_t kMaxBytes = 128; enum { kWhatLoad = 'load' }; struct FuzzAHandler : public AHandler { public: FuzzAHandler(std::function<void()> signalEosFunction) : mSignalEosFunction(signalEosFunction) {} protected: void onMessageReceived(const sp<AMessage>& msg) override { switch (msg->what()) { case kWhatLoad: { mSignalEosFunction(); break; } } return; } private: std::function<void()> mSignalEosFunction; }; struct FuzzMediaHTTPConnection : public MediaHTTPConnection { public: FuzzMediaHTTPConnection(FuzzedDataProvider* fdp) : mFdp(fdp) { mSize = mFdp->ConsumeIntegralInRange(kMinCapacity, kMaxCapacity); mData = mFdp->ConsumeBytes<uint8_t>(mSize); mSize = mData.size(); } virtual bool connect(const char* /* uri */, const KeyedVector<String8, String8>* /* headers */) { return mFdp->ConsumeBool(); } virtual void disconnect() { return; } virtual ssize_t readAt(off64_t offset, void* data, size_t size) { if (size <= mSize - offset) { data = mData.data() + offset; return size; } else { data = nullptr; return 0; } } virtual off64_t getSize() { return mSize; } virtual status_t getMIMEType(String8* /*mimeType*/) {return mFdp->ConsumeIntegral<status_t>();} virtual status_t getUri(String8* /*uri*/) {return mFdp->ConsumeIntegral<status_t>();} private: FuzzedDataProvider* mFdp = nullptr; std::vector<uint8_t> mData; size_t mSize = 0; }; struct FuzzMediaHTTPService : public MediaHTTPService { public: FuzzMediaHTTPService(FuzzedDataProvider* fdp) : mFdp(fdp) {} virtual sp<MediaHTTPConnection> makeHTTPConnection() { mediaHTTPConnection = sp<FuzzMediaHTTPConnection>::make(mFdp); return mediaHTTPConnection; } private: sp<FuzzMediaHTTPConnection> mediaHTTPConnection = nullptr; FuzzedDataProvider* mFdp = nullptr; }; class SDPLoaderFuzzer { public: SDPLoaderFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {} void process(); private: void signalEos(); bool mEosReached = false; std::mutex mMsgPostCompleteMutex; std::condition_variable mConditionalVariable; FuzzedDataProvider mFdp; }; void SDPLoaderFuzzer::signalEos() { mEosReached = true; mConditionalVariable.notify_one(); return; } void SDPLoaderFuzzer::process() { sp<FuzzAHandler> handler = sp<FuzzAHandler>::make(std::bind(&SDPLoaderFuzzer::signalEos, this)); sp<ALooper> looper = sp<ALooper>::make(); looper->start(); looper->registerHandler(handler); const sp<AMessage> notify = sp<AMessage>::make(kWhatLoad, handler); sp<SDPLoader> sdpLoader = sp<SDPLoader>::make(notify, mFdp.ConsumeIntegral<uint32_t>() /* flags */, sp<FuzzMediaHTTPService>::make(&mFdp) /* httpService */); KeyedVector<String8, String8> headers; for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange<size_t>(kMinCapacity, kMaxCapacity); ++idx) { headers.add(String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* key */, String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* value */); } sdpLoader->load(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* url */, &headers); std::unique_lock waitForMsgPostComplete(mMsgPostCompleteMutex); mConditionalVariable.wait(waitForMsgPostComplete, [this] { return mEosReached; }); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { SDPLoaderFuzzer sdpLoaderFuzzer(data, size); sdpLoaderFuzzer.process(); return 0; }