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(&params);
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