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