1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "batteryhdi_fuzz.h"
17
18 #include "securec.h"
19 #include <cstdint>
20 #include <cstdlib>
21 #include <datetime_ex.h>
22 #include <map>
23 #include <random>
24 #include <vector>
25
26 #include "v2_0/battery_interface_proxy.h"
27 #include "v2_0/ibattery_callback.h"
28 #include "v2_0/types.h"
29
30 using namespace OHOS::HDI::Battery::V2_0;
31 using namespace HDI::Battery;
32
33 namespace OHOS {
34 namespace HDI {
35 namespace Battery {
36 namespace V2_0 {
37 namespace {
38 class BatteryCallback : public IBatteryCallback {
39 public:
BatteryCallback()40 BatteryCallback() {};
~BatteryCallback()41 ~BatteryCallback() override {};
Update(const BatteryInfo & event)42 int32_t Update([[maybe_unused]] const BatteryInfo &event) override
43 {
44 return 0;
45 };
46 };
47 sptr<IBatteryInterface> g_batteryInterface = IBatteryInterface::Get();
48 } // namespace
49
Register(const uint8_t * data,size_t size)50 void Register(const uint8_t *data, size_t size)
51 {
52 uint8_t code;
53 if (size < sizeof(code)) {
54 return;
55 }
56 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
57 return;
58 }
59 sptr<IBatteryCallback> callback = new BatteryCallback();
60 g_batteryInterface->Register(callback);
61 g_batteryInterface->Register(nullptr);
62 }
63
UnRegister(const uint8_t * data,size_t size)64 void UnRegister(const uint8_t *data, size_t size)
65 {
66 uint8_t code;
67 if (size < sizeof(code)) {
68 return;
69 }
70 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
71 return;
72 }
73 g_batteryInterface->UnRegister();
74 }
75
ChangePath(const uint8_t * data,size_t size)76 void ChangePath(const uint8_t *data, size_t size)
77 {
78 std::string result(reinterpret_cast<const char *>(data), size);
79 g_batteryInterface->ChangePath(result);
80 }
81
GetCapacity(const uint8_t * data,size_t size)82 void GetCapacity(const uint8_t *data, size_t size)
83 {
84 int32_t out;
85 if (size < sizeof(out)) {
86 return;
87 }
88 if (memcpy_s(&out, sizeof(out), data, sizeof(out)) != EOK) {
89 return;
90 }
91 g_batteryInterface->GetCapacity(out);
92 }
93
GetVoltage(const uint8_t * data,size_t size)94 void GetVoltage(const uint8_t *data, size_t size)
95 {
96 int32_t out;
97 if (size < sizeof(out)) {
98 return;
99 }
100 if (memcpy_s(&out, sizeof(out), data, sizeof(out)) != EOK) {
101 return;
102 }
103 g_batteryInterface->GetVoltage(out);
104 }
105
GetTemperature(const uint8_t * data,size_t size)106 void GetTemperature(const uint8_t *data, size_t size)
107 {
108 int32_t out;
109 if (size < sizeof(out)) {
110 return;
111 }
112 if (memcpy_s(&out, sizeof(out), data, sizeof(out)) != EOK) {
113 return;
114 }
115 g_batteryInterface->GetTemperature(out);
116 }
117
GetHealthState(const uint8_t * data,size_t size)118 void GetHealthState(const uint8_t *data, size_t size)
119 {
120 uint8_t code;
121 if (size < sizeof(code)) {
122 return;
123 }
124 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
125 return;
126 }
127 BatteryHealthState state;
128 g_batteryInterface->GetHealthState(state);
129 }
130
GetPluggedType(const uint8_t * data,size_t size)131 void GetPluggedType(const uint8_t *data, size_t size)
132 {
133 uint8_t code;
134 if (size < sizeof(code)) {
135 return;
136 }
137 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
138 return;
139 }
140 BatteryPluggedType type;
141 g_batteryInterface->GetPluggedType(type);
142 }
143
GetChargeState(const uint8_t * data,size_t size)144 void GetChargeState(const uint8_t *data, size_t size)
145 {
146 uint8_t code;
147 if (size < sizeof(code)) {
148 return;
149 }
150 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
151 return;
152 }
153 BatteryChargeState state;
154 g_batteryInterface->GetChargeState(state);
155 }
156
GetPresent(const uint8_t * data,size_t size)157 void GetPresent(const uint8_t *data, size_t size)
158 {
159 uint8_t code;
160 if (size < sizeof(code)) {
161 return;
162 }
163 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
164 return;
165 }
166 bool present;
167 g_batteryInterface->GetPresent(present);
168 }
169
GetTechnology(const uint8_t * data,size_t size)170 void GetTechnology(const uint8_t *data, size_t size)
171 {
172 uint8_t code;
173 if (size < sizeof(code)) {
174 return;
175 }
176 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
177 return;
178 }
179 std::string str;
180 g_batteryInterface->GetTechnology(str);
181 }
182
GetTotalEnergy(const uint8_t * data,size_t size)183 void GetTotalEnergy(const uint8_t *data, size_t size)
184 {
185 int32_t out;
186 if (size < sizeof(out)) {
187 return;
188 }
189 if (memcpy_s(&out, sizeof(out), data, sizeof(out)) != EOK) {
190 return;
191 }
192 g_batteryInterface->GetTotalEnergy(out);
193 }
194
GetCurrentAverage(const uint8_t * data,size_t size)195 void GetCurrentAverage(const uint8_t *data, size_t size)
196 {
197 int32_t out;
198 if (size < sizeof(out)) {
199 return;
200 }
201 if (memcpy_s(&out, sizeof(out), data, sizeof(out)) != EOK) {
202 return;
203 }
204 g_batteryInterface->GetCurrentAverage(out);
205 }
206
GetCurrentNow(const uint8_t * data,size_t size)207 void GetCurrentNow(const uint8_t *data, size_t size)
208 {
209 int32_t out;
210 if (size < sizeof(out)) {
211 return;
212 }
213 if (memcpy_s(&out, sizeof(out), data, sizeof(out)) != EOK) {
214 return;
215 }
216 g_batteryInterface->GetCurrentNow(out);
217 }
218
GetRemainEnergy(const uint8_t * data,size_t size)219 void GetRemainEnergy(const uint8_t *data, size_t size)
220 {
221 int32_t out;
222 if (size < sizeof(out)) {
223 return;
224 }
225 if (memcpy_s(&out, sizeof(out), data, sizeof(out)) != EOK) {
226 return;
227 }
228 g_batteryInterface->GetRemainEnergy(out);
229 }
230
GetBatteryInfo(const uint8_t * data,size_t size)231 void GetBatteryInfo(const uint8_t *data, size_t size)
232 {
233 uint8_t code;
234 if (size < sizeof(code)) {
235 return;
236 }
237 if (memcpy_s(&code, sizeof(code), data, sizeof(code)) != EOK) {
238 return;
239 }
240 BatteryInfo info;
241 g_batteryInterface->GetBatteryInfo(info);
242 }
243
SetChargingLimit(const uint8_t * data,size_t size)244 void SetChargingLimit(const uint8_t *data, size_t size)
245 {
246 int32_t inputData;
247 if (size < sizeof(inputData)) {
248 return;
249 }
250 if (memcpy_s(&inputData, sizeof(inputData), data, sizeof(inputData)) != EOK) {
251 return;
252 }
253 int32_t minVectorSize = 0;
254 int32_t maxVectorSize = 5000;
255 int32_t length = (inputData < minVectorSize) ? minVectorSize : inputData;
256 length = (length > maxVectorSize) ? maxVectorSize : length;
257 std::vector<ChargingLimit> scLimit;
258 scLimit.resize(length);
259 for (auto &item : scLimit) {
260 item.type = ChargingLimitType(inputData);
261 item.protocol = std::string(reinterpret_cast<const char *>(data), size);
262 item.value = inputData;
263 }
264 g_batteryInterface->SetChargingLimit(scLimit);
265 }
266
267 static std::vector<std::function<void(const uint8_t *, size_t)>> fuzzFunc = {
268 &Register,
269 &UnRegister,
270 &ChangePath,
271 &GetCapacity,
272 &GetVoltage,
273 &GetTemperature,
274 &GetHealthState,
275 &GetPluggedType,
276 &GetChargeState,
277 &GetPresent,
278 &GetTechnology,
279 &GetTotalEnergy,
280 &GetCurrentAverage,
281 &GetCurrentNow,
282 &GetRemainEnergy,
283 &GetBatteryInfo,
284 &SetChargingLimit,
285 };
286
BatteryHdiFuzzTest(const uint8_t * data,size_t size)287 void BatteryHdiFuzzTest(const uint8_t *data, size_t size)
288 {
289 int32_t number = GetTickCount() % fuzzFunc.size();
290 fuzzFunc[number](data, size);
291 }
292 } // namespace V2_0
293 } // namespace Battery
294 } // namespace HDI
295 } // namespace OHOS
296
297 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)298 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
299 {
300 /* Run your code on data */
301 OHOS::HDI::Battery::V2_0::BatteryHdiFuzzTest(data, size);
302 return 0;
303 }
304