1 /*
2 * Copyright (c) 2022 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 #include "devicekvstore_fuzzer.h"
16
17 #include <string>
18 #include <sys/stat.h>
19 #include <vector>
20
21 #include "distributed_kv_data_manager.h"
22 #include "store_errno.h"
23
24 using namespace OHOS;
25 using namespace OHOS::DistributedKv;
26
27 namespace OHOS {
28 static std::shared_ptr<SingleKvStore> deviceKvStore_ = nullptr;
29
30 class DeviceObserverTestImpl : public KvStoreObserver {
31 public:
32 DeviceObserverTestImpl();
~DeviceObserverTestImpl()33 ~DeviceObserverTestImpl()
34 {
35 }
36 DeviceObserverTestImpl(const DeviceObserverTestImpl &) = delete;
37 DeviceObserverTestImpl &operator=(const DeviceObserverTestImpl &) = delete;
38 DeviceObserverTestImpl(DeviceObserverTestImpl &&) = delete;
39 DeviceObserverTestImpl &operator=(DeviceObserverTestImpl &&) = delete;
40
41 void OnChange(const ChangeNotification &changeNotification);
42 };
43
OnChange(const ChangeNotification & changeNotification)44 void DeviceObserverTestImpl::OnChange(const ChangeNotification &changeNotification)
45 {
46 }
47
DeviceObserverTestImpl()48 DeviceObserverTestImpl::DeviceObserverTestImpl()
49 {
50 }
51 class DeviceSyncCallbackTestImpl : public KvStoreSyncCallback {
52 public:
53 void SyncCompleted(const std::map<std::string, Status> &results);
54 };
55
SyncCompleted(const std::map<std::string,Status> & results)56 void DeviceSyncCallbackTestImpl::SyncCompleted(const std::map<std::string, Status> &results)
57 {
58 }
59
SetUpTestCase(void)60 void SetUpTestCase(void)
61 {
62 DistributedKvDataManager manager;
63 Options options = {
64 .createIfMissing = true,
65 .encrypt = false,
66 .autoSync = true,
67 .securityLevel = S1,
68 .kvStoreType = KvStoreType::DEVICE_COLLABORATION
69 };
70 options.area = EL1;
71 AppId appId = { "devicekvstorefuzzertest" };
72 options.baseDir = std::string("/data/service/el1/public/database/") + appId.appId;
73 /* define kvstore(database) name. */
74 StoreId storeId = { "fuzzer_device" };
75 mkdir(options.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
76 /* [create and] open and initialize kvstore instance. */
77 manager.GetSingleKvStore(options, appId, storeId, deviceKvStore_);
78 }
79
TearDown(void)80 void TearDown(void)
81 {
82 (void)remove("/data/service/el1/public/database/devicekvstorefuzzertest/key");
83 (void)remove("/data/service/el1/public/database/devicekvstorefuzzertest/kvdb");
84 (void)remove("/data/service/el1/public/database/devicekvstorefuzzertest");
85 }
86
PutFuzz(const uint8_t * data,size_t size)87 void PutFuzz(const uint8_t *data, size_t size)
88 {
89 std::string skey(data, data + size);
90 std::string svalue(data, data + size);
91 Key key = { skey };
92 Value val = { svalue };
93 deviceKvStore_->Put(key, val);
94 deviceKvStore_->Delete(key);
95 }
96
PutBatchFuzz(const uint8_t * data,size_t size)97 void PutBatchFuzz(const uint8_t *data, size_t size)
98 {
99 std::string skey(data, data + size);
100 std::string svalue(data, data + size);
101 std::vector<Entry> entries;
102 std::vector<Key> keys;
103 Entry entry1;
104 Entry entry2;
105 Entry entry3;
106 entry1.key = { skey + "test_key1" };
107 entry1.value = { svalue + "test_val1" };
108 entry2.key = { skey + "test_key2" };
109 entry2.value = { svalue + "test_val2" };
110 entry3.key = { skey + "test_key3" };
111 entry3.value = { svalue + "test_val3" };
112 entries.push_back(entry1);
113 entries.push_back(entry2);
114 entries.push_back(entry3);
115 keys.push_back(entry1.key);
116 keys.push_back(entry2.key);
117 keys.push_back(entry3.key);
118 deviceKvStore_->PutBatch(entries);
119 deviceKvStore_->DeleteBatch(keys);
120 }
121
GetFuzz(const uint8_t * data,size_t size)122 void GetFuzz(const uint8_t *data, size_t size)
123 {
124 std::string skey(data, data + size);
125 std::string svalue(data, data + size);
126 Key key = { skey };
127 Value val = { svalue };
128 Value val1;
129 deviceKvStore_->Put(key, val);
130 deviceKvStore_->Get(key, val1);
131 deviceKvStore_->Delete(key);
132 }
133
GetEntriesFuzz1(const uint8_t * data,size_t size)134 void GetEntriesFuzz1(const uint8_t *data, size_t size)
135 {
136 std::string prefix(data, data + size);
137 std::string keys = "test_";
138 size_t sum = 10;
139 std::vector<Entry> results;
140 for (size_t i = 0; i < sum; i++) {
141 deviceKvStore_->Put(prefix + keys + std::to_string(i), { keys + std::to_string(i) });
142 }
143 deviceKvStore_->GetEntries(prefix, results);
144 for (size_t i = 0; i < sum; i++) {
145 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
146 }
147 }
148
GetEntriesFuzz2(const uint8_t * data,size_t size)149 void GetEntriesFuzz2(const uint8_t *data, size_t size)
150 {
151 std::string prefix(data, data + size);
152 DataQuery dataQuery;
153 dataQuery.KeyPrefix(prefix);
154 std::string keys = "test_";
155 std::vector<Entry> entries;
156 size_t sum = 10;
157 for (size_t i = 0; i < sum; i++) {
158 deviceKvStore_->Put(prefix + keys + std::to_string(i), keys + std::to_string(i));
159 }
160 deviceKvStore_->GetEntries(dataQuery, entries);
161 for (size_t i = 0; i < sum; i++) {
162 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
163 }
164 }
165
SyncCallbackFuzz(const uint8_t * data,size_t size)166 void SyncCallbackFuzz(const uint8_t *data, size_t size)
167 {
168 auto syncCallback = std::make_shared<DeviceSyncCallbackTestImpl>();
169 deviceKvStore_->RegisterSyncCallback(syncCallback);
170
171 std::string prefix(data, data + size);
172 DataQuery dataQuery;
173 dataQuery.KeyPrefix(prefix);
174 std::string keys = "test_";
175 size_t sum = 10;
176 for (size_t i = 0; i < sum; i++) {
177 deviceKvStore_->Put(prefix + keys + std::to_string(i), keys + std::to_string(i));
178 }
179
180 std::map<std::string, Status> results;
181 syncCallback->SyncCompleted(results);
182
183 for (size_t i = 0; i < sum; i++) {
184 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
185 }
186 deviceKvStore_->UnRegisterSyncCallback();
187 }
188
GetResultSetFuzz1(const uint8_t * data,size_t size)189 void GetResultSetFuzz1(const uint8_t *data, size_t size)
190 {
191 std::string prefix(data, data + size);
192 std::string keys = "test_";
193 int position = static_cast<int>(size);
194 std::shared_ptr<KvStoreResultSet> resultSet;
195 size_t sum = 10;
196 for (size_t i = 0; i < sum; i++) {
197 deviceKvStore_->Put(prefix + keys + std::to_string(i), keys + std::to_string(i));
198 }
199 auto status = deviceKvStore_->GetResultSet(prefix, resultSet);
200 if (status != Status::SUCCESS || resultSet == nullptr) {
201 return;
202 }
203 resultSet->Move(position);
204 resultSet->MoveToPosition(position);
205 Entry entry;
206 resultSet->GetEntry(entry);
207 for (size_t i = 0; i < sum; i++) {
208 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
209 }
210 }
211
GetResultSetFuzz2(const uint8_t * data,size_t size)212 void GetResultSetFuzz2(const uint8_t *data, size_t size)
213 {
214 std::string prefix(data, data + size);
215 DataQuery dataQuery;
216 dataQuery.KeyPrefix(prefix);
217 std::string keys = "test_";
218 std::shared_ptr<KvStoreResultSet> resultSet;
219 size_t sum = 10;
220 for (size_t i = 0; i < sum; i++) {
221 deviceKvStore_->Put(prefix + keys + std::to_string(i), keys + std::to_string(i));
222 }
223 deviceKvStore_->GetResultSet(dataQuery, resultSet);
224 deviceKvStore_->CloseResultSet(resultSet);
225 for (size_t i = 0; i < sum; i++) {
226 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
227 }
228 }
229
GetResultSetFuzz3(const uint8_t * data,size_t size)230 void GetResultSetFuzz3(const uint8_t *data, size_t size)
231 {
232 std::string prefix(data, data + size);
233 DataQuery dataQuery;
234 dataQuery.KeyPrefix(prefix);
235 std::string keys = "test_";
236 std::shared_ptr<KvStoreResultSet> resultSet;
237 size_t sum = 10;
238 for (size_t i = 0; i < sum; i++) {
239 deviceKvStore_->Put(prefix + keys + std::to_string(i), keys + std::to_string(i));
240 }
241 deviceKvStore_->GetResultSet(dataQuery, resultSet);
242 auto status = deviceKvStore_->GetResultSet(prefix, resultSet);
243 if (status != Status::SUCCESS || resultSet == nullptr) {
244 return;
245 }
246 int cnt = resultSet->GetCount();
247 if (static_cast<int>(size) != cnt) {
248 return;
249 }
250 resultSet->GetPosition();
251 resultSet->IsBeforeFirst();
252 resultSet->IsFirst();
253 resultSet->MoveToPrevious();
254 resultSet->IsBeforeFirst();
255 resultSet->IsFirst();
256 while (resultSet->MoveToNext()) {
257 Entry entry;
258 resultSet->GetEntry(entry);
259 }
260 Entry entry;
261 resultSet->GetEntry(entry);
262 resultSet->IsLast();
263 resultSet->IsAfterLast();
264 resultSet->MoveToNext();
265 resultSet->IsLast();
266 resultSet->IsAfterLast();
267 resultSet->Move(1);
268 resultSet->IsLast();
269 resultSet->IsAfterLast();
270 resultSet->MoveToFirst();
271 resultSet->GetEntry(entry);
272 resultSet->MoveToLast();
273 resultSet->GetEntry(entry);
274
275 for (size_t i = 0; i < sum; i++) {
276 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
277 }
278 }
279
GetCountFuzz1(const uint8_t * data,size_t size)280 void GetCountFuzz1(const uint8_t *data, size_t size)
281 {
282 int count;
283 std::string prefix(data, data + size);
284 DataQuery query;
285 query.KeyPrefix(prefix);
286 std::string keys = "test_";
287 size_t sum = 10;
288 for (size_t i = 0; i < sum; i++) {
289 deviceKvStore_->Put(prefix + keys + std::to_string(i), keys + std::to_string(i));
290 }
291 deviceKvStore_->GetCount(query, count);
292 for (size_t i = 0; i < sum; i++) {
293 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
294 }
295 }
296
GetCountFuzz2(const uint8_t * data,size_t size)297 void GetCountFuzz2(const uint8_t *data, size_t size)
298 {
299 int count;
300 size_t sum = 10;
301 std::vector<std::string> keys;
302 std::string prefix(data, data + size);
303 for (size_t i = 0; i < sum; i++) {
304 keys.push_back(prefix);
305 }
306 DataQuery query;
307 query.InKeys(keys);
308 std::string skey = "test_";
309 for (size_t i = 0; i < sum; i++) {
310 deviceKvStore_->Put(prefix + skey + std::to_string(i), skey + std::to_string(i));
311 }
312 deviceKvStore_->GetCount(query, count);
313 for (size_t i = 0; i < sum; i++) {
314 deviceKvStore_->Delete(prefix + skey + std::to_string(i));
315 }
316 }
317
SyncFuzz1(const uint8_t * data,size_t size)318 void SyncFuzz1(const uint8_t *data, size_t size)
319 {
320 size_t sum = 10;
321 std::string skey = "test_";
322 for (size_t i = 0; i < sum; i++) {
323 deviceKvStore_->Put(skey + std::to_string(i), skey + std::to_string(i));
324 }
325 std::string deviceId(data, data + size);
326 std::vector<std::string> deviceIds = { deviceId };
327 uint32_t allowedDelayMs = 200;
328 deviceKvStore_->Sync(deviceIds, SyncMode::PUSH, allowedDelayMs);
329 for (size_t i = 0; i < sum; i++) {
330 deviceKvStore_->Delete(skey + std::to_string(i));
331 }
332 }
333
SyncFuzz2(const uint8_t * data,size_t size)334 void SyncFuzz2(const uint8_t *data, size_t size)
335 {
336 size_t sum = 10;
337 std::string skey = "test_";
338 for (size_t i = 0; i < sum; i++) {
339 deviceKvStore_->Put(skey + std::to_string(i), skey + std::to_string(i));
340 }
341 std::string deviceId(data, data + size);
342 std::vector<std::string> deviceIds = { deviceId };
343 DataQuery dataQuery;
344 dataQuery.KeyPrefix("name");
345 deviceKvStore_->Sync(deviceIds, SyncMode::PULL, dataQuery, nullptr);
346 for (size_t i = 0; i < sum; i++) {
347 deviceKvStore_->Delete(skey + std::to_string(i));
348 }
349 }
350
SubscribeKvStoreFuzz(const uint8_t * data,size_t size)351 void SubscribeKvStoreFuzz(const uint8_t *data, size_t size)
352 {
353 std::string prefix(data, data + size);
354 DataQuery dataQuery;
355 dataQuery.KeyPrefix(prefix);
356 std::string keys = "test_";
357 size_t sum = 10;
358 for (size_t i = 0; i < sum; i++) {
359 deviceKvStore_->Put(prefix + keys + std::to_string(i), keys + std::to_string(i));
360 }
361 auto observer = std::make_shared<DeviceObserverTestImpl>();
362 deviceKvStore_->SubscribeKvStore(SubscribeType::SUBSCRIBE_TYPE_ALL, observer);
363 deviceKvStore_->UnSubscribeKvStore(SubscribeType::SUBSCRIBE_TYPE_ALL, observer);
364 for (size_t i = 0; i < sum; i++) {
365 deviceKvStore_->Delete(prefix + keys + std::to_string(i));
366 }
367 }
368
RemoveDeviceDataFuzz(const uint8_t * data,size_t size)369 void RemoveDeviceDataFuzz(const uint8_t *data, size_t size)
370 {
371 size_t sum = 10;
372 std::string deviceId(data, data + size);
373 std::vector<Entry> input;
374 auto cmp = [](const Key &entry, const Key &sentry) { return entry.Data() < sentry.Data(); };
375 std::map<Key, Value, decltype(cmp)> dictionary(cmp);
376 for (size_t i = 0; i < sum; ++i) {
377 Entry entry;
378 entry.key = std::to_string(i).append("_k");
379 entry.value = std::to_string(i).append("_v");
380 dictionary[entry.key] = entry.value;
381 input.push_back(entry);
382 }
383 deviceKvStore_->PutBatch(input);
384 deviceKvStore_->RemoveDeviceData(deviceId);
385 deviceKvStore_->RemoveDeviceData("");
386
387 for (size_t i = 0; i < sum; i++) {
388 deviceKvStore_->Delete(std::to_string(i).append("_k"));
389 }
390 }
391
GetSecurityLevelFuzz(const uint8_t * data,size_t size)392 void GetSecurityLevelFuzz(const uint8_t *data, size_t size)
393 {
394 size_t sum = 10;
395 std::vector<std::string> keys;
396 std::string prefix(data, data + size);
397 for (size_t i = 0; i < sum; i++) {
398 keys.push_back(prefix);
399 }
400 std::string skey = "test_";
401 for (size_t i = 0; i < sum; i++) {
402 deviceKvStore_->Put(prefix + skey + std::to_string(i), skey + std::to_string(i));
403 }
404 SecurityLevel securityLevel;
405 deviceKvStore_->GetSecurityLevel(securityLevel);
406 for (size_t i = 0; i < sum; i++) {
407 deviceKvStore_->Delete(prefix + skey + std::to_string(i));
408 }
409 }
410
SyncParamFuzz(const uint8_t * data,size_t size)411 void SyncParamFuzz(const uint8_t *data, size_t size)
412 {
413 size_t sum = 10;
414 std::vector<std::string> keys;
415 std::string prefix(data, data + size);
416 for (size_t i = 0; i < sum; i++) {
417 keys.push_back(prefix);
418 }
419 std::string skey = "test_";
420 for (size_t i = 0; i < sum; i++) {
421 deviceKvStore_->Put(prefix + skey + std::to_string(i), skey + std::to_string(i));
422 }
423
424 KvSyncParam syncParam { 500 };
425 deviceKvStore_->SetSyncParam(syncParam);
426
427 KvSyncParam syncParamRet;
428 deviceKvStore_->GetSyncParam(syncParamRet);
429
430 for (size_t i = 0; i < sum; i++) {
431 deviceKvStore_->Delete(prefix + skey + std::to_string(i));
432 }
433 }
434
SetCapabilityEnabledFuzz(const uint8_t * data,size_t size)435 void SetCapabilityEnabledFuzz(const uint8_t *data, size_t size)
436 {
437 size_t sum = 10;
438 std::vector<std::string> keys;
439 std::string prefix(data, data + size);
440 for (size_t i = 0; i < sum; i++) {
441 keys.push_back(prefix);
442 }
443 std::string skey = "test_";
444 for (size_t i = 0; i < sum; i++) {
445 deviceKvStore_->Put(prefix + skey + std::to_string(i), skey + std::to_string(i));
446 }
447
448 deviceKvStore_->SetCapabilityEnabled(true);
449 deviceKvStore_->SetCapabilityEnabled(false);
450
451 for (size_t i = 0; i < sum; i++) {
452 deviceKvStore_->Delete(prefix + skey + std::to_string(i));
453 }
454 }
455
SetCapabilityRangeFuzz(const uint8_t * data,size_t size)456 void SetCapabilityRangeFuzz(const uint8_t *data, size_t size)
457 {
458 std::string label(data, data + size);
459 std::vector<std::string> local = { label + "_local1", label + "_local2" };
460 std::vector<std::string> remote = { label + "_remote1", label + "_remote2" };
461 deviceKvStore_->SetCapabilityRange(local, remote);
462 }
463
SubscribeWithQueryFuzz(const uint8_t * data,size_t size)464 void SubscribeWithQueryFuzz(const uint8_t *data, size_t size)
465 {
466 std::string deviceId(data, data + size);
467 std::vector<std::string> deviceIds = { deviceId + "_1", deviceId + "_2" };
468 DataQuery dataQuery;
469 dataQuery.KeyPrefix("name");
470 deviceKvStore_->SubscribeWithQuery(deviceIds, dataQuery);
471 deviceKvStore_->UnsubscribeWithQuery(deviceIds, dataQuery);
472 }
473
UnSubscribeWithQueryFuzz(const uint8_t * data,size_t size)474 void UnSubscribeWithQueryFuzz(const uint8_t *data, size_t size)
475 {
476 std::string deviceId(data, data + size);
477 std::vector<std::string> deviceIds = { deviceId + "_1", deviceId + "_2" };
478 DataQuery dataQuery;
479 dataQuery.KeyPrefix("name");
480 deviceKvStore_->UnsubscribeWithQuery(deviceIds, dataQuery);
481 }
482 } // namespace OHOS
483
484 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)485 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
486 {
487 /* Run your code on data */
488 OHOS::SetUpTestCase();
489 OHOS::PutFuzz(data, size);
490 OHOS::PutBatchFuzz(data, size);
491 OHOS::GetFuzz(data, size);
492 OHOS::GetEntriesFuzz1(data, size);
493 OHOS::GetEntriesFuzz2(data, size);
494 OHOS::GetResultSetFuzz1(data, size);
495 OHOS::GetResultSetFuzz2(data, size);
496 OHOS::GetResultSetFuzz3(data, size);
497 OHOS::GetCountFuzz1(data, size);
498 OHOS::GetCountFuzz2(data, size);
499 OHOS::SyncFuzz1(data, size);
500 OHOS::SyncFuzz2(data, size);
501 OHOS::SubscribeKvStoreFuzz(data, size);
502 OHOS::RemoveDeviceDataFuzz(data, size);
503 OHOS::GetSecurityLevelFuzz(data, size);
504 OHOS::SyncCallbackFuzz(data, size);
505 OHOS::SyncParamFuzz(data, size);
506 OHOS::SetCapabilityEnabledFuzz(data, size);
507 OHOS::SetCapabilityRangeFuzz(data, size);
508 OHOS::SubscribeWithQueryFuzz(data, size);
509 OHOS::UnSubscribeWithQueryFuzz(data, size);
510 OHOS::TearDown();
511 return 0;
512 }