• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "relationalstore_fuzzer.h"
16 
17 #include <fuzzer/FuzzedDataProvider.h>
18 #include <iostream>
19 #include <sys/stat.h>
20 
21 #include "grd_api_manager.h"
22 #include "rdb_errno.h"
23 #include "relational_store.h"
24 #include "relational_store_error_code.h"
25 #include "relational_store_impl.h"
26 #include "accesstoken_kit.h"
27 
28 static constexpr const char *RDB_TEST_PATH = "/data/storage/el2/database/com.ohos.example.distributedndk/entry/";
29 
30 using namespace OHOS::NativeRdb;
31 using namespace OHOS::RdbNdk;
32 using namespace OHOS::Security::AccessToken;
33 
CreateAndSetCryptoParam(FuzzedDataProvider & provider,OH_Rdb_ConfigV2 * config)34 void CreateAndSetCryptoParam(FuzzedDataProvider &provider, OH_Rdb_ConfigV2 *config)
35 {
36     if (config == nullptr) {
37         return;
38     }
39     OH_Rdb_CryptoParam *param = OH_Rdb_CreateCryptoParam();
40     int32_t length = provider.ConsumeIntegral<int32_t>();
41     std::vector<uint8_t> key = provider.ConsumeBytes<uint8_t>(length);
42     int64_t iterator = provider.ConsumeIntegral<int32_t>();
43     int32_t algo = provider.ConsumeIntegral<int32_t>();
44     int64_t size = provider.ConsumeIntegral<int32_t>();
45 
46     OH_Crypto_SetEncryptionKey(param, key.data(), key.size());
47     OH_Crypto_SetIteration(param, iterator);
48     OH_Crypto_SetEncryptionAlgo(param, algo);
49     OH_Crypto_SetHmacAlgo(param, algo);
50     OH_Crypto_SetKdfAlgo(param, algo);
51     OH_Crypto_SetCryptoPageSize(param, size);
52     OH_Rdb_SetCryptoParam(config, param);
53     if (param != nullptr) {
54         OH_Rdb_DestroyCryptoParam(param);
55     }
56 }
57 
58 constexpr int RDB_CONFIG_PLUGINS_MAX = 16;
CreateAndSetPlugins(FuzzedDataProvider & provider,OH_Rdb_ConfigV2 * config)59 void CreateAndSetPlugins(FuzzedDataProvider &provider, OH_Rdb_ConfigV2 *config)
60 {
61     uint32_t count = provider.ConsumeIntegralInRange(0, RDB_CONFIG_PLUGINS_MAX);
62     std::vector<std::string> plugins;
63     for (uint32_t i = 0; i < count; i++) {
64         plugins.push_back(provider.ConsumeRandomLengthString());
65     }
66     const char *arr[RDB_CONFIG_PLUGINS_MAX] = {nullptr};
67     for (size_t i = 0; i < count; ++i) {
68         arr[i] = plugins[i].c_str();
69     }
70     OH_Rdb_SetPlugins(config, arr, count);
71 }
72 
AppendApi20ConfigV2(FuzzedDataProvider & provider,struct OH_Rdb_ConfigV2 * configV2)73 void AppendApi20ConfigV2(FuzzedDataProvider &provider, struct OH_Rdb_ConfigV2 *configV2)
74 {
75     if (configV2 == nullptr) {
76         return;
77     }
78     bool readOnly = provider.ConsumeBool();
79     OH_Rdb_SetReadOnly(configV2, readOnly);
80     std::string customDir = provider.ConsumeRandomLengthString();
81     OH_Rdb_SetCustomDir(configV2, customDir.c_str());
82     CreateAndSetPlugins(provider, configV2);
83     CreateAndSetCryptoParam(provider, configV2);
84 }
85 
CreateOHRdbConfigV2(FuzzedDataProvider & provider)86 struct OH_Rdb_ConfigV2 *CreateOHRdbConfigV2(FuzzedDataProvider &provider)
87 {
88     struct OH_Rdb_ConfigV2 *configV2 = OH_Rdb_CreateConfig();
89     if (configV2 == nullptr) {
90         return nullptr;
91     }
92     std::string databaseDir = provider.ConsumeRandomLengthString();
93     OH_Rdb_SetDatabaseDir(configV2, databaseDir.c_str());
94     std::string storeName = provider.ConsumeRandomLengthString();
95     OH_Rdb_SetStoreName(configV2, storeName.c_str());
96     std::string bundleName = provider.ConsumeRandomLengthString();
97     OH_Rdb_SetBundleName(configV2, bundleName.c_str());
98     std::string bmoduleName = provider.ConsumeRandomLengthString();
99     OH_Rdb_SetModuleName(configV2, bmoduleName.c_str());
100     bool isEncrypted = provider.ConsumeBool();
101     OH_Rdb_SetEncrypted(configV2, isEncrypted);
102     int securityLevel = provider.ConsumeIntegral<int>();
103     OH_Rdb_SetSecurityLevel(configV2, securityLevel);
104     int area = provider.ConsumeIntegral<int>();
105     OH_Rdb_SetArea(configV2, area);
106     int dbType = provider.ConsumeIntegral<int>();
107     OH_Rdb_SetDbType(configV2, dbType);
108 
109     Rdb_Tokenizer tokenizer =
110         static_cast<Rdb_Tokenizer>(provider.ConsumeIntegralInRange<int>(RDB_NONE_TOKENIZER, RDB_CUSTOM_TOKENIZER));
111     bool isSupported = false;
112     OH_Rdb_IsTokenizerSupported(tokenizer, &isSupported);
113     {
114         Rdb_Tokenizer tokenizer =
115             static_cast<Rdb_Tokenizer>(provider.ConsumeIntegralInRange<int>(RDB_NONE_TOKENIZER, RDB_CUSTOM_TOKENIZER));
116         OH_Rdb_SetTokenizer(configV2, tokenizer);
117     }
118     bool isPersistent = provider.ConsumeBool();
119     OH_Rdb_SetPersistent(configV2, isPersistent);
120     int typeCount = 0;
121     OH_Rdb_GetSupportedDbType(&typeCount);
122     return configV2;
123 }
124 
CreateOHVObject(FuzzedDataProvider & provider)125 OH_VObject *CreateOHVObject(FuzzedDataProvider &provider)
126 {
127     OH_VObject *valueObject = OH_Rdb_CreateValueObject();
128     if (valueObject == nullptr) {
129         return nullptr;
130     }
131     std::string value = provider.ConsumeRandomLengthString();
132     valueObject->putText(valueObject, value.c_str());
133     return valueObject;
134 }
135 
CreateOHVBucket(FuzzedDataProvider & provider)136 OH_VBucket *CreateOHVBucket(FuzzedDataProvider &provider)
137 {
138     OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
139     if (valueBucket == nullptr) {
140         return nullptr;
141     }
142     {
143         std::string key = provider.ConsumeRandomLengthString();
144         int64_t value = provider.ConsumeIntegral<int64_t>();
145         valueBucket->putInt64(valueBucket, key.c_str(), value);
146     }
147     {
148         std::string key = provider.ConsumeRandomLengthString();
149         std::string value = provider.ConsumeRandomLengthString();
150         valueBucket->putText(valueBucket, key.c_str(), value.c_str());
151     }
152     {
153         std::string key = provider.ConsumeRandomLengthString();
154         float value = provider.ConsumeFloatingPoint<float>();
155         valueBucket->putReal(valueBucket, key.c_str(), value);
156     }
157     {
158         std::string key = provider.ConsumeRandomLengthString();
159         const int minBlobSize = 1;
160         const int maxBlobSize = 50;
161         size_t blobSize = provider.ConsumeIntegralInRange<size_t>(minBlobSize, maxBlobSize);
162         std::vector<uint8_t> blobData = provider.ConsumeBytes<uint8_t>(blobSize);
163         valueBucket->putBlob(valueBucket, key.c_str(), blobData.data(), blobData.size());
164     }
165     return valueBucket;
166 }
167 
RelationalStoreCAPIFuzzTest(FuzzedDataProvider & provider)168 void RelationalStoreCAPIFuzzTest(FuzzedDataProvider &provider)
169 {
170     struct OH_Rdb_ConfigV2 *configV2 = CreateOHRdbConfigV2(provider);
171     if (configV2 == nullptr) {
172         return;
173     }
174     OH_VObject *valueObject = CreateOHVObject(provider);
175     if (valueObject == nullptr) {
176         return;
177     }
178     std::string table = provider.ConsumeRandomLengthString();
179     OH_Predicates *predicates = OH_Rdb_CreatePredicates(table.c_str());
180     if (predicates == nullptr) {
181         return;
182     }
183     {
184         std::string value = provider.ConsumeRandomLengthString();
185         predicates->equalTo(predicates, value.c_str(), valueObject);
186     }
187 
188     OH_VBucket *valueBucket = CreateOHVBucket(provider);
189     if (valueBucket == nullptr) {
190         return;
191     }
192 
193     int errCode = 0;
194     static OH_Rdb_Store *OHRdbStore = OH_Rdb_CreateOrOpen(configV2, &errCode);
195     {
196         table = provider.ConsumeRandomLengthString();
197         OH_Rdb_Insert(OHRdbStore, table.c_str(), valueBucket);
198     }
199     OH_Data_VBuckets *list = OH_VBuckets_Create();
200     OH_VBuckets_PutRow(list, valueBucket);
201     {
202         table = provider.ConsumeRandomLengthString();
203         Rdb_ConflictResolution resolution = static_cast<Rdb_ConflictResolution>(
204             provider.ConsumeIntegralInRange<int>(RDB_CONFLICT_NONE, RDB_CONFLICT_REPLACE));
205         int64_t changes = 0;
206         OH_Rdb_BatchInsert(OHRdbStore, table.c_str(), list, resolution, &changes);
207     }
208     OH_Rdb_Update(OHRdbStore, valueBucket, predicates);
209     valueBucket->destroy(valueBucket);
210     predicates->destroy(predicates);
211     valueObject->destroy(valueObject);
212     OH_VBuckets_Destroy(list);
213     OH_Rdb_CloseStore(OHRdbStore);
214     OH_Rdb_DeleteStoreV2(configV2);
215     OH_Rdb_DestroyConfig(configV2);
216 }
217 
RelationalConfigV2Capi20FuzzTest(FuzzedDataProvider & provider)218 void RelationalConfigV2Capi20FuzzTest(FuzzedDataProvider &provider)
219 {
220     static bool runEndFlag = false;
221     struct OH_Rdb_ConfigV2 *configV2 = CreateOHRdbConfigV2(provider);
222     if (configV2 == nullptr) {
223         return;
224     }
225     AppendApi20ConfigV2(provider, configV2);
226     OH_Rdb_DestroyConfig(configV2);
227     if (!runEndFlag) {
228         runEndFlag = true;
229         std::cout << "RelationalConfigV2Capi20FuzzTest end" << std::endl;
230     }
231 }
232 
233 OH_Rdb_ConfigV2* g_normalConfig = nullptr;
MockHap(void)234 void MockHap(void)
235 {
236     HapInfoParams info = {
237         .userID = 100,
238         .bundleName = "com.example.distributed",
239         .instIndex = 0,
240         .appIDDesc = "com.example.distributed"
241     };
242     PermissionDef infoManagerTestPermDef = {
243         .permissionName = "ohos.permission.test",
244         .bundleName = "com.example.distributed",
245         .grantMode = 1,
246         .availableLevel = APL_NORMAL,
247         .label = "label",
248         .labelId = 1,
249         .description = "open the door",
250         .descriptionId = 1
251     };
252     PermissionStateFull infoManagerTestState = {
253         .permissionName = "ohos.permission.test",
254         .isGeneral = true,
255         .resDeviceID = { "local" },
256         .grantStatus = { PermissionState::PERMISSION_GRANTED },
257         .grantFlags = { 1 }
258     };
259     HapPolicyParams policy = {
260         .apl = APL_NORMAL,
261         .domain = "test.domain",
262         .permList = { infoManagerTestPermDef },
263         .permStateList = { infoManagerTestState }
264     };
265     AccessTokenKit::AllocHapToken(info, policy);
266 }
267 
GetFuzzerNormalStore()268 OH_Rdb_Store *GetFuzzerNormalStore()
269 {
270     MockHap();
271     // 0770 is permission
272     mkdir(RDB_TEST_PATH, 0770);
273     g_normalConfig = OH_Rdb_CreateConfig();
274     OH_Rdb_SetDatabaseDir(g_normalConfig, RDB_TEST_PATH);
275     OH_Rdb_SetStoreName(g_normalConfig, "rdb_store_test.db");
276     OH_Rdb_SetBundleName(g_normalConfig, "com.ohos.example.distributedndk");
277     OH_Rdb_SetEncrypted(g_normalConfig, false);
278     OH_Rdb_SetSecurityLevel(g_normalConfig, OH_Rdb_SecurityLevel::S1);
279     OH_Rdb_SetArea(g_normalConfig, RDB_SECURITY_AREA_EL1);
280     int errCode = 0;
281     OH_Rdb_Store *store = OH_Rdb_CreateOrOpen(g_normalConfig, &errCode);
282     return store;
283 }
284 
DeleteFuzzerNormalStroe(OH_Rdb_Store * store)285 void DeleteFuzzerNormalStroe(OH_Rdb_Store *store)
286 {
287     if (store != nullptr) {
288         delete store;
289     }
290     OH_Rdb_DeleteStoreV2(g_normalConfig);
291     OH_Rdb_DestroyConfig(g_normalConfig);
292     g_normalConfig = nullptr;
293 }
294 
295 
InitFuzzerNormalStore(OH_Rdb_Store * store)296 void InitFuzzerNormalStore(OH_Rdb_Store *store)
297 {
298     if (store == nullptr) {
299         return;
300     }
301     char createTableSql[] = "CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, "
302                             "data3 FLOAT, data4 BLOB, data5 TEXT);";
303     OH_Rdb_Execute(store, createTableSql);
304 }
305 
GetFuzzerNormalValuesBucket()306 OH_VBucket* GetFuzzerNormalValuesBucket()
307 {
308     OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
309     valueBucket->putInt64(valueBucket, "id", 1);
310     valueBucket->putText(valueBucket, "data1", "zhangSan");
311     // 12800 stub number
312     valueBucket->putInt64(valueBucket, "data2", 12800);
313     // 100.1 stub number
314     valueBucket->putReal(valueBucket, "data3", 100.1);
315     valueBucket->putText(valueBucket, "data5", "ABCDEFG");
316     return valueBucket;
317 }
318 
DeleteFuzzerNormalValuesBucket(OH_VBucket * valueBucket)319 void DeleteFuzzerNormalValuesBucket(OH_VBucket *valueBucket)
320 {
321     if (valueBucket == nullptr) {
322         return;
323     }
324     valueBucket->destroy(valueBucket);
325 }
326 
GetCapi20Predicates(FuzzedDataProvider & provider,std::string table)327 OH_Predicates* GetCapi20Predicates(FuzzedDataProvider &provider, std::string table)
328 {
329     OH_Predicates *predicates = OH_Rdb_CreatePredicates(table.c_str());
330     if (predicates == nullptr) {
331         return nullptr;
332     }
333     std::string value = provider.ConsumeRandomLengthString();
334     OH_VObject *valueObject = CreateOHVObject(provider);
335     if (valueObject == nullptr) {
336         predicates->destroy(predicates);
337         return nullptr;
338     }
339     predicates->equalTo(predicates, value.c_str(), valueObject);
340     valueObject->destroy(valueObject);
341     return predicates;
342 }
343 
DeleteCapi20Predicates(OH_Predicates * predicates)344 void DeleteCapi20Predicates(OH_Predicates *predicates)
345 {
346     if (predicates != nullptr) {
347         return;
348     }
349     predicates->destroy(predicates);
350 }
351 
352 
RelationalStoreCapi20FuzzTest(FuzzedDataProvider & provider)353 void RelationalStoreCapi20FuzzTest(FuzzedDataProvider &provider)
354 {
355     static bool runEndFlag = false;
356     int64_t rowId;
357     std::string table = "test";
358     Rdb_ConflictResolution resolution = static_cast<Rdb_ConflictResolution>(
359         provider.ConsumeIntegralInRange<int>(RDB_CONFLICT_NONE, RDB_CONFLICT_REPLACE));
360 
361     OH_Rdb_Store *store = GetFuzzerNormalStore();
362     OH_VBucket *valueBucket = GetFuzzerNormalValuesBucket();
363     OH_Predicates *predicates = GetCapi20Predicates(provider, table);
364     do {
365         if (store == nullptr || valueBucket == nullptr || predicates == nullptr) {
366             break;
367         }
368         OH_Rdb_InsertWithConflictResolution(store, table.c_str(), valueBucket, resolution, &rowId);
369         OH_Rdb_UpdateWithConflictResolution(store, valueBucket, predicates, resolution, &rowId);
370         if (!runEndFlag) {
371             runEndFlag = true;
372             std::cout << "RelationalStoreCapi20FuzzTest end" << std::endl;
373         }
374     } while (0);
375 
376     DeleteCapi20Predicates(predicates);
377     DeleteFuzzerNormalValuesBucket(valueBucket);
378     DeleteFuzzerNormalStroe(store);
379 }
380 
RelationalStoreAttatchFuzzTest(FuzzedDataProvider & provider)381 void RelationalStoreAttatchFuzzTest(FuzzedDataProvider &provider)
382 {
383     static bool runEndFlag = false;
384     OH_Rdb_Store *store = GetFuzzerNormalStore();
385     OH_Rdb_ConfigV2 *attachConfig = OH_Rdb_CreateConfig();
386     int64_t waitTime = provider.ConsumeIntegral<int32_t>();
387     do {
388         if (store == nullptr || attachConfig == nullptr) {
389             break;
390         }
391         OH_Rdb_SetDatabaseDir(attachConfig, RDB_TEST_PATH);
392         OH_Rdb_SetStoreName(attachConfig, "rdb_attach_store_test.db");
393         OH_Rdb_SetBundleName(attachConfig, "com.ohos.example.distributedndk");
394         OH_Rdb_SetEncrypted(attachConfig, false);
395         OH_Rdb_SetSecurityLevel(attachConfig, OH_Rdb_SecurityLevel::S1);
396         OH_Rdb_SetArea(attachConfig, RDB_SECURITY_AREA_EL1);
397 
398         size_t attachedNumber = 0;
399         OH_Rdb_Attach(store, attachConfig, "attach_test", waitTime, &attachedNumber);
400         OH_Rdb_Detach(store, "attach_test", waitTime, &attachedNumber);
401         if (!runEndFlag) {
402             runEndFlag = true;
403             std::cout << "RelationalStoreAttatchFuzzTest end" << std::endl;
404         }
405     } while (0);
406 
407     OH_Rdb_DestroyConfig(attachConfig);
408     DeleteFuzzerNormalStroe(store);
409 }
410 
411 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)412 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
413 {
414     /* Run your code on data */
415     FuzzedDataProvider provider(data, size);
416 
417     RelationalStoreCAPIFuzzTest(provider);
418 
419     // Test OH_Rdb_SetCryptoParam
420     RelationalConfigV2Capi20FuzzTest(provider);
421 
422     // Test OH_Rdb_InsertWithConflictResolution and OH_Rdb_UpdateWithConflictResolution
423     RelationalStoreCapi20FuzzTest(provider);
424 
425     // Test OH_Rdb_Attach and OH_Rdb_Detach
426     RelationalStoreAttatchFuzzTest(provider);
427     return 0;
428 }
429