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