1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <codecserviceregistrant/CodecServiceRegistrant.h>
18
19 #include "../CodecServiceRegistrant.cpp"
20 #include "fuzzer/FuzzedDataProvider.h"
21 #include <C2Config.h>
22 #include <C2Param.h>
23 #include <android/api-level.h>
24
25 using namespace std;
26
27 constexpr char kServiceName[] = "software";
28
29 class CodecServiceRegistrantFuzzer {
30 public:
31 void process(const uint8_t *data, size_t size);
~CodecServiceRegistrantFuzzer()32 ~CodecServiceRegistrantFuzzer() {
33 delete mH2C2;
34 if (mInputSize) {
35 delete mInputSize;
36 }
37 if (mSampleRateInfo) {
38 delete mSampleRateInfo;
39 }
40 if (mChannelCountInfo) {
41 delete mChannelCountInfo;
42 }
43 }
44
45 private:
46 void initH2C2ComponentStore();
47 void invokeH2C2ComponentStore();
48 void invokeConfigSM();
49 void invokeQuerySM();
50 H2C2ComponentStore *mH2C2 = nullptr;
51 C2StreamPictureSizeInfo::input *mInputSize = nullptr;
52 C2StreamSampleRateInfo::output *mSampleRateInfo = nullptr;
53 C2StreamChannelCountInfo::output *mChannelCountInfo = nullptr;
54 C2Param::Index mIndex = C2StreamProfileLevelInfo::output::PARAM_TYPE;
55 C2StreamFrameRateInfo::output mFrameRate;
56 FuzzedDataProvider *mFDP = nullptr;
57 };
58
initH2C2ComponentStore()59 void CodecServiceRegistrantFuzzer::initH2C2ComponentStore() {
60 using namespace ::android::hardware::media::c2;
61 shared_ptr<C2ComponentStore> store =
62 android::GetCodec2PlatformComponentStore();
63 if (!store) {
64 return;
65 }
66
67 int32_t platformVersion = android_get_device_api_level();
68 if (platformVersion >= __ANDROID_API_S__) {
69 android::sp<V1_2::IComponentStore> storeV1_2 =
70 new V1_2::utils::ComponentStore(store);
71 if (storeV1_2->registerAsService(string(kServiceName)) != android::OK) {
72 return;
73 }
74 } else if (platformVersion == __ANDROID_API_R__) {
75 android::sp<V1_1::IComponentStore> storeV1_1 =
76 new V1_1::utils::ComponentStore(store);
77 if (storeV1_1->registerAsService(string(kServiceName)) != android::OK) {
78 return;
79 }
80 } else if (platformVersion == __ANDROID_API_Q__) {
81 android::sp<V1_0::IComponentStore> storeV1_0 =
82 new V1_0::utils::ComponentStore(store);
83 if (storeV1_0->registerAsService(string(kServiceName)) != android::OK) {
84 return;
85 }
86 }
87 else {
88 return;
89 }
90
91 string const preferredStoreName = string(kServiceName);
92 sp<V1_0::IComponentStore> preferredStore =
93 V1_0::IComponentStore::getService(preferredStoreName.c_str());
94 mH2C2 = new H2C2ComponentStore(preferredStore);
95 }
96
invokeConfigSM()97 void CodecServiceRegistrantFuzzer::invokeConfigSM() {
98 vector<C2Param *> configParams;
99 uint32_t width = mFDP->ConsumeIntegral<uint32_t>();
100 uint32_t height = mFDP->ConsumeIntegral<uint32_t>();
101 uint32_t samplingRate = mFDP->ConsumeIntegral<uint32_t>();
102 uint32_t channels = mFDP->ConsumeIntegral<uint32_t>();
103 if (mFDP->ConsumeBool()) {
104 mInputSize = new C2StreamPictureSizeInfo::input(0u, width, height);
105 configParams.push_back(mInputSize);
106 } else {
107 if (mFDP->ConsumeBool()) {
108 mSampleRateInfo = new C2StreamSampleRateInfo::output(0u, samplingRate);
109 configParams.push_back(mSampleRateInfo);
110 }
111 if (mFDP->ConsumeBool()) {
112 mChannelCountInfo = new C2StreamChannelCountInfo::output(0u, channels);
113 configParams.push_back(mChannelCountInfo);
114 }
115 }
116 vector<unique_ptr<C2SettingResult>> failures;
117 mH2C2->config_sm(configParams, &failures);
118 }
119
invokeQuerySM()120 void CodecServiceRegistrantFuzzer::invokeQuerySM() {
121 vector<C2Param *> stackParams;
122 vector<C2Param::Index> heapParamIndices;
123 if (mFDP->ConsumeBool()) {
124 stackParams = {};
125 heapParamIndices = {};
126 } else {
127 uint32_t stream = mFDP->ConsumeIntegral<uint32_t>();
128 mFrameRate.setStream(stream);
129 stackParams.push_back(&mFrameRate);
130 heapParamIndices.push_back(mIndex);
131 }
132 vector<unique_ptr<C2Param>> heapParams;
133 mH2C2->query_sm(stackParams, heapParamIndices, &heapParams);
134 }
135
invokeH2C2ComponentStore()136 void CodecServiceRegistrantFuzzer::invokeH2C2ComponentStore() {
137 initH2C2ComponentStore();
138 shared_ptr<C2Component> component;
139 shared_ptr<C2ComponentInterface> interface;
140 string c2String = mFDP->ConsumeRandomLengthString();
141 mH2C2->createComponent(c2String, &component);
142 mH2C2->createInterface(c2String, &interface);
143 invokeConfigSM();
144 invokeQuerySM();
145
146 vector<shared_ptr<C2ParamDescriptor>> params;
147 mH2C2->querySupportedParams_nb(¶ms);
148
149 C2StoreIonUsageInfo usageInfo;
150 std::vector<C2FieldSupportedValuesQuery> query = {
151 C2FieldSupportedValuesQuery::Possible(
152 C2ParamField::Make(usageInfo, usageInfo.usage)),
153 C2FieldSupportedValuesQuery::Possible(
154 C2ParamField::Make(usageInfo, usageInfo.capacity)),
155 };
156 mH2C2->querySupportedValues_sm(query);
157
158 mH2C2->getName();
159 shared_ptr<C2ParamReflector> paramReflector = mH2C2->getParamReflector();
160 if (paramReflector) {
161 paramReflector->describe(C2ComponentDomainSetting::CORE_INDEX);
162 }
163 mH2C2->listComponents();
164 shared_ptr<C2GraphicBuffer> src;
165 shared_ptr<C2GraphicBuffer> dst;
166 mH2C2->copyBuffer(src, dst);
167 }
168
process(const uint8_t * data,size_t size)169 void CodecServiceRegistrantFuzzer::process(const uint8_t *data, size_t size) {
170 mFDP = new FuzzedDataProvider(data, size);
171 invokeH2C2ComponentStore();
172 /** RegisterCodecServicesWithExistingThreadpool() is called here to improve
173 * code coverage as currently it is not called in codecServiceRegistrant.cpp */
174 RegisterCodecServicesWithExistingThreadpool();
175 delete mFDP;
176 }
177
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)178 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
179 CodecServiceRegistrantFuzzer codecServiceRegistrantFuzzer;
180 codecServiceRegistrantFuzzer.process(data, size);
181 return 0;
182 }
183