Loading services/mediacodec/registrant/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ package { default_applicable_licenses: ["frameworks_av_services_mediacodec_license"], } cc_library_shared { cc_library { name: "libmedia_codecserviceregistrant", vendor_available: true, srcs: [ Loading services/mediacodec/registrant/fuzzer/Android.bp 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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_fuzz { name: "codecServiceRegistrant_fuzzer", srcs: [ "codecServiceRegistrant_fuzzer.cpp", ], static_libs: [ "libmedia_codecserviceregistrant", ], header_libs: [ "libmedia_headers", ], defaults: [ "libcodec2-hidl-defaults", ], fuzz_config: { cc: [ "android-media-fuzzing-reports@google.com", ], componentid: 155276, }, } services/mediacodec/registrant/fuzzer/README.md 0 → 100644 +56 −0 Original line number Diff line number Diff line # Fuzzer for libmedia_codecserviceregistrant ## Plugin Design Considerations The fuzzer plugin for libmedia_codecserviceregistrant is designed based on the understanding of the library and tries to achieve the following: ##### Maximize code coverage The configuration parameters are not hardcoded, but instead selected based on incoming data. This ensures more code paths are reached by the fuzzer. libmedia_codecserviceregistrant supports the following parameters: 1. C2String (parameter name: `c2String`) 2. Width (parameter name: `width`) 3. Height (parameter name: `height`) 4. SamplingRate (parameter name: `samplingRate`) 5. Channels (parameter name: `channels`) 6. Stream (parameter name: `stream`) | Parameter| Valid Values| Configured Value| |------------- |-------------| ----- | | `c2String` |`String` | Value obtained from FuzzedDataProvider| | `width` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `height` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `samplingRate` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `channels` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `stream` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| This also ensures that the plugin is always deterministic for any given input. ##### Maximize utilization of input data The plugin feeds the entire input data to the libmedia_codecserviceregistrant module. This ensures that the plugin tolerates any kind of input (empty, huge, malformed, etc) and doesnt `exit()` on any input and thereby increasing the chance of identifying vulnerabilities. ## Build This describes steps to build codecServiceRegistrant_fuzzer binary. ### Android #### Steps to build Build the fuzzer ``` $ mm -j$(nproc) codecServiceRegistrant_fuzzer ``` #### Steps to run To run on device ``` $ adb sync data $ adb shell /data/fuzz/${TARGET_ARCH}/codecServiceRegistrant_fuzzer/codecServiceRegistrant_fuzzer ``` ## References: * http://llvm.org/docs/LibFuzzer.html * https://github.com/google/oss-fuzz services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp 0 → 100644 +155 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 "../CodecServiceRegistrant.cpp" #include "fuzzer/FuzzedDataProvider.h" #include <C2Config.h> #include <C2Param.h> using namespace std; constexpr char kServiceName[] = "software"; class CodecServiceRegistrantFuzzer { public: void process(const uint8_t *data, size_t size); ~CodecServiceRegistrantFuzzer() { delete mH2C2; if (mInputSize) { delete mInputSize; } if (mSampleRateInfo) { delete mSampleRateInfo; } if (mChannelCountInfo) { delete mChannelCountInfo; } } private: void initH2C2ComponentStore(); void invokeH2C2ComponentStore(); void invokeConfigSM(); void invokeQuerySM(); H2C2ComponentStore *mH2C2 = nullptr; C2StreamPictureSizeInfo::input *mInputSize = nullptr; C2StreamSampleRateInfo::output *mSampleRateInfo = nullptr; C2StreamChannelCountInfo::output *mChannelCountInfo = nullptr; C2Param::Index mIndex = C2StreamProfileLevelInfo::output::PARAM_TYPE; C2StreamFrameRateInfo::output mFrameRate; FuzzedDataProvider *mFDP = nullptr; }; void CodecServiceRegistrantFuzzer::initH2C2ComponentStore() { using namespace ::android::hardware::media::c2; shared_ptr<C2ComponentStore> store = android::GetCodec2PlatformComponentStore(); if (!store) { return; } android::sp<V1_1::IComponentStore> storeV1_1 = new V1_1::utils::ComponentStore(store); if (storeV1_1->registerAsService(string(kServiceName)) != android::OK) { return; } string const preferredStoreName = string(kServiceName); sp<IComponentStore> preferredStore = IComponentStore::getService(preferredStoreName.c_str()); mH2C2 = new H2C2ComponentStore(preferredStore); } void CodecServiceRegistrantFuzzer::invokeConfigSM() { vector<C2Param *> configParams; uint32_t width = mFDP->ConsumeIntegral<uint32_t>(); uint32_t height = mFDP->ConsumeIntegral<uint32_t>(); uint32_t samplingRate = mFDP->ConsumeIntegral<uint32_t>(); uint32_t channels = mFDP->ConsumeIntegral<uint32_t>(); if (mFDP->ConsumeBool()) { mInputSize = new C2StreamPictureSizeInfo::input(0u, width, height); configParams.push_back(mInputSize); } else { if (mFDP->ConsumeBool()) { mSampleRateInfo = new C2StreamSampleRateInfo::output(0u, samplingRate); configParams.push_back(mSampleRateInfo); } if (mFDP->ConsumeBool()) { mChannelCountInfo = new C2StreamChannelCountInfo::output(0u, channels); configParams.push_back(mChannelCountInfo); } } vector<unique_ptr<C2SettingResult>> failures; mH2C2->config_sm(configParams, &failures); } void CodecServiceRegistrantFuzzer::invokeQuerySM() { vector<C2Param *> stackParams; vector<C2Param::Index> heapParamIndices; if (mFDP->ConsumeBool()) { stackParams = {}; heapParamIndices = {}; } else { uint32_t stream = mFDP->ConsumeIntegral<uint32_t>(); mFrameRate.setStream(stream); stackParams.push_back(&mFrameRate); heapParamIndices.push_back(mIndex); } vector<unique_ptr<C2Param>> heapParams; mH2C2->query_sm(stackParams, heapParamIndices, &heapParams); } void CodecServiceRegistrantFuzzer::invokeH2C2ComponentStore() { initH2C2ComponentStore(); shared_ptr<C2Component> component; shared_ptr<C2ComponentInterface> interface; string c2String = mFDP->ConsumeRandomLengthString(); mH2C2->createComponent(c2String, &component); mH2C2->createInterface(c2String, &interface); invokeConfigSM(); invokeQuerySM(); vector<shared_ptr<C2ParamDescriptor>> params; mH2C2->querySupportedParams_nb(¶ms); C2StoreIonUsageInfo usageInfo; std::vector<C2FieldSupportedValuesQuery> query = { C2FieldSupportedValuesQuery::Possible( C2ParamField::Make(usageInfo, usageInfo.usage)), C2FieldSupportedValuesQuery::Possible( C2ParamField::Make(usageInfo, usageInfo.capacity)), }; mH2C2->querySupportedValues_sm(query); mH2C2->getName(); mH2C2->getParamReflector(); mH2C2->listComponents(); shared_ptr<C2GraphicBuffer> src; shared_ptr<C2GraphicBuffer> dst; mH2C2->copyBuffer(src, dst); } void CodecServiceRegistrantFuzzer::process(const uint8_t *data, size_t size) { mFDP = new FuzzedDataProvider(data, size); invokeH2C2ComponentStore(); /** RegisterCodecServices is called here to improve code coverage */ /** as currently it is not called by codecServiceRegistrant */ RegisterCodecServices(); delete mFDP; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { CodecServiceRegistrantFuzzer codecServiceRegistrantFuzzer; codecServiceRegistrantFuzzer.process(data, size); return 0; } Loading
services/mediacodec/registrant/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ package { default_applicable_licenses: ["frameworks_av_services_mediacodec_license"], } cc_library_shared { cc_library { name: "libmedia_codecserviceregistrant", vendor_available: true, srcs: [ Loading
services/mediacodec/registrant/fuzzer/Android.bp 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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_fuzz { name: "codecServiceRegistrant_fuzzer", srcs: [ "codecServiceRegistrant_fuzzer.cpp", ], static_libs: [ "libmedia_codecserviceregistrant", ], header_libs: [ "libmedia_headers", ], defaults: [ "libcodec2-hidl-defaults", ], fuzz_config: { cc: [ "android-media-fuzzing-reports@google.com", ], componentid: 155276, }, }
services/mediacodec/registrant/fuzzer/README.md 0 → 100644 +56 −0 Original line number Diff line number Diff line # Fuzzer for libmedia_codecserviceregistrant ## Plugin Design Considerations The fuzzer plugin for libmedia_codecserviceregistrant is designed based on the understanding of the library and tries to achieve the following: ##### Maximize code coverage The configuration parameters are not hardcoded, but instead selected based on incoming data. This ensures more code paths are reached by the fuzzer. libmedia_codecserviceregistrant supports the following parameters: 1. C2String (parameter name: `c2String`) 2. Width (parameter name: `width`) 3. Height (parameter name: `height`) 4. SamplingRate (parameter name: `samplingRate`) 5. Channels (parameter name: `channels`) 6. Stream (parameter name: `stream`) | Parameter| Valid Values| Configured Value| |------------- |-------------| ----- | | `c2String` |`String` | Value obtained from FuzzedDataProvider| | `width` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `height` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `samplingRate` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `channels` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| | `stream` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider| This also ensures that the plugin is always deterministic for any given input. ##### Maximize utilization of input data The plugin feeds the entire input data to the libmedia_codecserviceregistrant module. This ensures that the plugin tolerates any kind of input (empty, huge, malformed, etc) and doesnt `exit()` on any input and thereby increasing the chance of identifying vulnerabilities. ## Build This describes steps to build codecServiceRegistrant_fuzzer binary. ### Android #### Steps to build Build the fuzzer ``` $ mm -j$(nproc) codecServiceRegistrant_fuzzer ``` #### Steps to run To run on device ``` $ adb sync data $ adb shell /data/fuzz/${TARGET_ARCH}/codecServiceRegistrant_fuzzer/codecServiceRegistrant_fuzzer ``` ## References: * http://llvm.org/docs/LibFuzzer.html * https://github.com/google/oss-fuzz
services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp 0 → 100644 +155 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 "../CodecServiceRegistrant.cpp" #include "fuzzer/FuzzedDataProvider.h" #include <C2Config.h> #include <C2Param.h> using namespace std; constexpr char kServiceName[] = "software"; class CodecServiceRegistrantFuzzer { public: void process(const uint8_t *data, size_t size); ~CodecServiceRegistrantFuzzer() { delete mH2C2; if (mInputSize) { delete mInputSize; } if (mSampleRateInfo) { delete mSampleRateInfo; } if (mChannelCountInfo) { delete mChannelCountInfo; } } private: void initH2C2ComponentStore(); void invokeH2C2ComponentStore(); void invokeConfigSM(); void invokeQuerySM(); H2C2ComponentStore *mH2C2 = nullptr; C2StreamPictureSizeInfo::input *mInputSize = nullptr; C2StreamSampleRateInfo::output *mSampleRateInfo = nullptr; C2StreamChannelCountInfo::output *mChannelCountInfo = nullptr; C2Param::Index mIndex = C2StreamProfileLevelInfo::output::PARAM_TYPE; C2StreamFrameRateInfo::output mFrameRate; FuzzedDataProvider *mFDP = nullptr; }; void CodecServiceRegistrantFuzzer::initH2C2ComponentStore() { using namespace ::android::hardware::media::c2; shared_ptr<C2ComponentStore> store = android::GetCodec2PlatformComponentStore(); if (!store) { return; } android::sp<V1_1::IComponentStore> storeV1_1 = new V1_1::utils::ComponentStore(store); if (storeV1_1->registerAsService(string(kServiceName)) != android::OK) { return; } string const preferredStoreName = string(kServiceName); sp<IComponentStore> preferredStore = IComponentStore::getService(preferredStoreName.c_str()); mH2C2 = new H2C2ComponentStore(preferredStore); } void CodecServiceRegistrantFuzzer::invokeConfigSM() { vector<C2Param *> configParams; uint32_t width = mFDP->ConsumeIntegral<uint32_t>(); uint32_t height = mFDP->ConsumeIntegral<uint32_t>(); uint32_t samplingRate = mFDP->ConsumeIntegral<uint32_t>(); uint32_t channels = mFDP->ConsumeIntegral<uint32_t>(); if (mFDP->ConsumeBool()) { mInputSize = new C2StreamPictureSizeInfo::input(0u, width, height); configParams.push_back(mInputSize); } else { if (mFDP->ConsumeBool()) { mSampleRateInfo = new C2StreamSampleRateInfo::output(0u, samplingRate); configParams.push_back(mSampleRateInfo); } if (mFDP->ConsumeBool()) { mChannelCountInfo = new C2StreamChannelCountInfo::output(0u, channels); configParams.push_back(mChannelCountInfo); } } vector<unique_ptr<C2SettingResult>> failures; mH2C2->config_sm(configParams, &failures); } void CodecServiceRegistrantFuzzer::invokeQuerySM() { vector<C2Param *> stackParams; vector<C2Param::Index> heapParamIndices; if (mFDP->ConsumeBool()) { stackParams = {}; heapParamIndices = {}; } else { uint32_t stream = mFDP->ConsumeIntegral<uint32_t>(); mFrameRate.setStream(stream); stackParams.push_back(&mFrameRate); heapParamIndices.push_back(mIndex); } vector<unique_ptr<C2Param>> heapParams; mH2C2->query_sm(stackParams, heapParamIndices, &heapParams); } void CodecServiceRegistrantFuzzer::invokeH2C2ComponentStore() { initH2C2ComponentStore(); shared_ptr<C2Component> component; shared_ptr<C2ComponentInterface> interface; string c2String = mFDP->ConsumeRandomLengthString(); mH2C2->createComponent(c2String, &component); mH2C2->createInterface(c2String, &interface); invokeConfigSM(); invokeQuerySM(); vector<shared_ptr<C2ParamDescriptor>> params; mH2C2->querySupportedParams_nb(¶ms); C2StoreIonUsageInfo usageInfo; std::vector<C2FieldSupportedValuesQuery> query = { C2FieldSupportedValuesQuery::Possible( C2ParamField::Make(usageInfo, usageInfo.usage)), C2FieldSupportedValuesQuery::Possible( C2ParamField::Make(usageInfo, usageInfo.capacity)), }; mH2C2->querySupportedValues_sm(query); mH2C2->getName(); mH2C2->getParamReflector(); mH2C2->listComponents(); shared_ptr<C2GraphicBuffer> src; shared_ptr<C2GraphicBuffer> dst; mH2C2->copyBuffer(src, dst); } void CodecServiceRegistrantFuzzer::process(const uint8_t *data, size_t size) { mFDP = new FuzzedDataProvider(data, size); invokeH2C2ComponentStore(); /** RegisterCodecServices is called here to improve code coverage */ /** as currently it is not called by codecServiceRegistrant */ RegisterCodecServices(); delete mFDP; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { CodecServiceRegistrantFuzzer codecServiceRegistrantFuzzer; codecServiceRegistrantFuzzer.process(data, size); return 0; }