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