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