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 #include "../CodecServiceRegistrant.cpp"
17 #include "fuzzer/FuzzedDataProvider.h"
18 #include <C2Config.h>
19 #include <C2Param.h>
20 #include <android/api-level.h>
21
22 using namespace std;
23
24 constexpr char kServiceName[] = "software";
25
26 class CodecServiceRegistrantFuzzer {
27 public:
28 void process(const uint8_t *data, size_t size);
~CodecServiceRegistrantFuzzer()29 ~CodecServiceRegistrantFuzzer() {
30 delete mH2C2;
31 if (mInputSize) {
32 delete mInputSize;
33 }
34 if (mSampleRateInfo) {
35 delete mSampleRateInfo;
36 }
37 if (mChannelCountInfo) {
38 delete mChannelCountInfo;
39 }
40 }
41
42 private:
43 void initH2C2ComponentStore();
44 void invokeH2C2ComponentStore();
45 void invokeConfigSM();
46 void invokeQuerySM();
47 H2C2ComponentStore *mH2C2 = nullptr;
48 C2StreamPictureSizeInfo::input *mInputSize = nullptr;
49 C2StreamSampleRateInfo::output *mSampleRateInfo = nullptr;
50 C2StreamChannelCountInfo::output *mChannelCountInfo = nullptr;
51 C2Param::Index mIndex = C2StreamProfileLevelInfo::output::PARAM_TYPE;
52 C2StreamFrameRateInfo::output mFrameRate;
53 FuzzedDataProvider *mFDP = nullptr;
54 };
55
initH2C2ComponentStore()56 void CodecServiceRegistrantFuzzer::initH2C2ComponentStore() {
57 using namespace ::android::hardware::media::c2;
58 shared_ptr<C2ComponentStore> store =
59 android::GetCodec2PlatformComponentStore();
60 if (!store) {
61 return;
62 }
63
64 int32_t platformVersion = android_get_device_api_level();
65 if (platformVersion >= __ANDROID_API_S__) {
66 android::sp<V1_2::IComponentStore> storeV1_2 =
67 new V1_2::utils::ComponentStore(store);
68 if (storeV1_2->registerAsService(string(kServiceName)) != android::OK) {
69 return;
70 }
71 } else if (platformVersion == __ANDROID_API_R__) {
72 android::sp<V1_1::IComponentStore> storeV1_1 =
73 new V1_1::utils::ComponentStore(store);
74 if (storeV1_1->registerAsService(string(kServiceName)) != android::OK) {
75 return;
76 }
77 } else if (platformVersion == __ANDROID_API_Q__) {
78 android::sp<V1_0::IComponentStore> storeV1_0 =
79 new V1_0::utils::ComponentStore(store);
80 if (storeV1_0->registerAsService(string(kServiceName)) != android::OK) {
81 return;
82 }
83 }
84 else {
85 return;
86 }
87
88 string const preferredStoreName = string(kServiceName);
89 sp<V1_0::IComponentStore> preferredStore =
90 V1_0::IComponentStore::getService(preferredStoreName.c_str());
91 mH2C2 = new H2C2ComponentStore(preferredStore);
92 }
93
invokeConfigSM()94 void CodecServiceRegistrantFuzzer::invokeConfigSM() {
95 vector<C2Param *> configParams;
96 uint32_t width = mFDP->ConsumeIntegral<uint32_t>();
97 uint32_t height = mFDP->ConsumeIntegral<uint32_t>();
98 uint32_t samplingRate = mFDP->ConsumeIntegral<uint32_t>();
99 uint32_t channels = mFDP->ConsumeIntegral<uint32_t>();
100 if (mFDP->ConsumeBool()) {
101 mInputSize = new C2StreamPictureSizeInfo::input(0u, width, height);
102 configParams.push_back(mInputSize);
103 } else {
104 if (mFDP->ConsumeBool()) {
105 mSampleRateInfo = new C2StreamSampleRateInfo::output(0u, samplingRate);
106 configParams.push_back(mSampleRateInfo);
107 }
108 if (mFDP->ConsumeBool()) {
109 mChannelCountInfo = new C2StreamChannelCountInfo::output(0u, channels);
110 configParams.push_back(mChannelCountInfo);
111 }
112 }
113 vector<unique_ptr<C2SettingResult>> failures;
114 mH2C2->config_sm(configParams, &failures);
115 }
116
invokeQuerySM()117 void CodecServiceRegistrantFuzzer::invokeQuerySM() {
118 vector<C2Param *> stackParams;
119 vector<C2Param::Index> heapParamIndices;
120 if (mFDP->ConsumeBool()) {
121 stackParams = {};
122 heapParamIndices = {};
123 } else {
124 uint32_t stream = mFDP->ConsumeIntegral<uint32_t>();
125 mFrameRate.setStream(stream);
126 stackParams.push_back(&mFrameRate);
127 heapParamIndices.push_back(mIndex);
128 }
129 vector<unique_ptr<C2Param>> heapParams;
130 mH2C2->query_sm(stackParams, heapParamIndices, &heapParams);
131 }
132
invokeH2C2ComponentStore()133 void CodecServiceRegistrantFuzzer::invokeH2C2ComponentStore() {
134 initH2C2ComponentStore();
135 shared_ptr<C2Component> component;
136 shared_ptr<C2ComponentInterface> interface;
137 string c2String = mFDP->ConsumeRandomLengthString();
138 mH2C2->createComponent(c2String, &component);
139 mH2C2->createInterface(c2String, &interface);
140 invokeConfigSM();
141 invokeQuerySM();
142
143 vector<shared_ptr<C2ParamDescriptor>> params;
144 mH2C2->querySupportedParams_nb(¶ms);
145
146 C2StoreIonUsageInfo usageInfo;
147 std::vector<C2FieldSupportedValuesQuery> query = {
148 C2FieldSupportedValuesQuery::Possible(
149 C2ParamField::Make(usageInfo, usageInfo.usage)),
150 C2FieldSupportedValuesQuery::Possible(
151 C2ParamField::Make(usageInfo, usageInfo.capacity)),
152 };
153 mH2C2->querySupportedValues_sm(query);
154
155 mH2C2->getName();
156 shared_ptr<C2ParamReflector> paramReflector = mH2C2->getParamReflector();
157 if (paramReflector) {
158 paramReflector->describe(C2ComponentDomainSetting::CORE_INDEX);
159 }
160 mH2C2->listComponents();
161 shared_ptr<C2GraphicBuffer> src;
162 shared_ptr<C2GraphicBuffer> dst;
163 mH2C2->copyBuffer(src, dst);
164 }
165
process(const uint8_t * data,size_t size)166 void CodecServiceRegistrantFuzzer::process(const uint8_t *data, size_t size) {
167 mFDP = new FuzzedDataProvider(data, size);
168 invokeH2C2ComponentStore();
169 /** RegisterCodecServices is called here to improve code coverage */
170 /** as currently it is not called by codecServiceRegistrant */
171 RegisterCodecServices();
172 delete mFDP;
173 }
174
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)175 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
176 CodecServiceRegistrantFuzzer codecServiceRegistrantFuzzer;
177 codecServiceRegistrantFuzzer.process(data, size);
178 return 0;
179 }
180