1 /*
2 * Copyright (c) 2024 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 "medialibraryappuripermissionoperations_fuzzer.h"
17
18 #include <cstdint>
19 #include <string>
20 #include <vector>
21 #include <fuzzer/FuzzedDataProvider.h>
22
23 #include "ability_context_impl.h"
24 #include "medialibrary_app_uri_permission_operations.h"
25 #include "datashare_predicates.h"
26 #include "media_app_uri_permission_column.h"
27 #include "media_column.h"
28 #include "media_file_utils.h"
29 #include "media_log.h"
30 #include "medialibrary_command.h"
31 #include "medialibrary_data_manager.h"
32 #include "medialibrary_errno.h"
33 #include "medialibrary_operation.h"
34 #include "medialibrary_photo_operations.h"
35 #include "medialibrary_unistore.h"
36 #include "medialibrary_unistore_manager.h"
37 #include "medialibrary_kvstore_manager.h"
38 #include "rdb_store.h"
39 #include "rdb_utils.h"
40 #include "userfile_manager_types.h"
41 #include "values_bucket.h"
42
43 namespace OHOS {
44 using namespace std;
45 using namespace DataShare;
46 const int32_t PERMISSION_DEFAULT = -1;
47 const int32_t URI_DEFAULT = 0;
48 const int32_t BatchInsertNumber = 5;
49 static const int32_t E_ERR = -1;
50 static const int32_t NUM_BYTES = 1;
51 static const int32_t MAX_PERMISSION_TYPE = 6;
52 static const int32_t MAX_URI_TYPE = 2;
53 static const int32_t MAX_DATA = 1;
54 std::shared_ptr<Media::MediaLibraryRdbStore> g_rdbStore;
55 FuzzedDataProvider *FDP = nullptr;
56
FuzzPermissionType()57 static int FuzzPermissionType()
58 {
59 vector<int> vecPermissionType;
60 vecPermissionType.assign(Media::AppUriPermissionColumn::PERMISSION_TYPES_ALL.begin(),
61 Media::AppUriPermissionColumn::PERMISSION_TYPES_ALL.end());
62 vecPermissionType.push_back(PERMISSION_DEFAULT);
63 uint8_t data = FDP->ConsumeIntegralInRange<uint8_t>(0, MAX_PERMISSION_TYPE);
64 return vecPermissionType[data];
65 }
66
FuzzUriType()67 static int FuzzUriType()
68 {
69 vector<int> vecUriType;
70 vecUriType.assign(Media::AppUriPermissionColumn::URI_TYPES_ALL.begin(),
71 Media::AppUriPermissionColumn::URI_TYPES_ALL.end());
72 vecUriType.push_back(URI_DEFAULT);
73 uint8_t data = FDP->ConsumeIntegralInRange<uint8_t>(0, MAX_URI_TYPE);
74 return vecUriType[data];
75 }
76
FuzzMimeTypeAndDisplayNameExtension(string & mimeType,string & displayName)77 static inline void FuzzMimeTypeAndDisplayNameExtension(string &mimeType, string &displayName)
78 {
79 uint8_t data = FDP->ConsumeIntegralInRange<uint8_t>(0, MAX_DATA);
80 mimeType = Media::MIMETYPE_FUZZER_LISTS[data];
81 displayName = FDP->ConsumeBytesAsString(NUM_BYTES) + Media::DISPLAY_NAME_EXTENSION_FUZZER_LISTS[data];
82 }
83
InsertPhotoAsset(string photoId)84 static int32_t InsertPhotoAsset(string photoId)
85 {
86 if (g_rdbStore == nullptr) {
87 return E_ERR;
88 }
89 NativeRdb::ValuesBucket values;
90 values.PutString(Media::PhotoColumn::PHOTO_ID, photoId);
91 values.PutString(Media::MediaColumn::MEDIA_FILE_PATH, FDP->ConsumeBytesAsString(NUM_BYTES));
92
93 string mimeType = "undefined";
94 string displayName = ".undefined";
95 FuzzMimeTypeAndDisplayNameExtension(mimeType, displayName);
96 values.PutString(Media::MediaColumn::MEDIA_NAME, displayName);
97 values.PutString(Media::MediaColumn::MEDIA_MIME_TYPE, mimeType);
98
99 int64_t fileId = 0;
100 g_rdbStore->Insert(fileId, Media::PhotoColumn::PHOTOS_TABLE, values);
101 return static_cast<int32_t>(fileId);
102 }
103
HandleInsertOperationFuzzer(string appId,int32_t photoId,int32_t permissionType,int32_t uriType)104 static void HandleInsertOperationFuzzer(string appId, int32_t photoId, int32_t permissionType, int32_t uriType)
105 {
106 DataShareValuesBucket values;
107 values.Put(Media::AppUriPermissionColumn::APP_ID, appId);
108 values.Put(Media::AppUriPermissionColumn::FILE_ID, photoId);
109 values.Put(Media::AppUriPermissionColumn::PERMISSION_TYPE, permissionType);
110 values.Put(Media::AppUriPermissionColumn::URI_TYPE, uriType);
111 Media::MediaLibraryCommand cmd(Media::OperationObject::MEDIA_APP_URI_PERMISSION, Media::OperationType::CREATE,
112 Media::MediaLibraryApi::API_10);
113 NativeRdb::ValuesBucket rdbValue = RdbDataShareAdapter::RdbUtils::ToValuesBucket(values);
114 cmd.SetValueBucket(rdbValue);
115 Media::MediaLibraryAppUriPermissionOperations::HandleInsertOperation(cmd);
116 }
117
DeleteOperationFuzzer(string appId,int32_t photoId,int32_t permissionType)118 static void DeleteOperationFuzzer(string appId, int32_t photoId, int32_t permissionType)
119 {
120 DataSharePredicates predicates;
121 predicates.And()->EqualTo(Media::AppUriPermissionColumn::APP_ID, appId);
122 predicates.And()->EqualTo(Media::AppUriPermissionColumn::FILE_ID, photoId);
123 predicates.And()->EqualTo(Media::AppUriPermissionColumn::PERMISSION_TYPE, permissionType);
124 NativeRdb::RdbPredicates rdbPredicate = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates,
125 Media::AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
126 Media::MediaLibraryAppUriPermissionOperations::DeleteOperation(rdbPredicate);
127 }
128
BatchInsertFuzzer()129 static void BatchInsertFuzzer()
130 {
131 vector<DataShare::DataShareValuesBucket> dataShareValues;
132 for (int32_t i = 0; i < BatchInsertNumber; i++) {
133 DataShareValuesBucket value;
134 string photoId = FDP->ConsumeBytesAsString(NUM_BYTES);
135 int32_t fileId = InsertPhotoAsset(photoId);
136 string appId = FDP->ConsumeBytesAsString(NUM_BYTES);
137 value.Put(Media::AppUriPermissionColumn::APP_ID, appId);
138 value.Put(Media::AppUriPermissionColumn::FILE_ID, fileId);
139 int32_t permissionType = FuzzPermissionType();
140 value.Put(Media::AppUriPermissionColumn::PERMISSION_TYPE, permissionType);
141 int32_t uriType = FuzzUriType();
142 value.Put(Media::AppUriPermissionColumn::URI_TYPE, uriType);
143 dataShareValues.push_back(value);
144 }
145 Media::MediaLibraryCommand cmd(Media::OperationObject::MEDIA_APP_URI_PERMISSION, Media::OperationType::CREATE,
146 Media::MediaLibraryApi::API_10);
147 Media::MediaLibraryAppUriPermissionOperations::BatchInsert(cmd, dataShareValues);
148 }
149
BatchInsertInnerFuzzer()150 static void BatchInsertInnerFuzzer()
151 {
152 vector<DataShare::DataShareValuesBucket> dataShareValues;
153 for (int32_t i = 0; i < BatchInsertNumber; i++) {
154 DataShareValuesBucket value;
155 string photoId = FDP->ConsumeBytesAsString(NUM_BYTES);
156 int32_t fileId = InsertPhotoAsset(photoId);
157 string appId = FDP->ConsumeBytesAsString(NUM_BYTES);
158 value.Put(Media::AppUriPermissionColumn::APP_ID, appId);
159 value.Put(Media::AppUriPermissionColumn::FILE_ID, fileId);
160 int32_t permissionType = FuzzPermissionType();
161 value.Put(Media::AppUriPermissionColumn::PERMISSION_TYPE, permissionType);
162 int32_t uriType = FuzzUriType();
163 value.Put(Media::AppUriPermissionColumn::URI_TYPE, uriType);
164 value.Put(Media::AppUriPermissionColumn::DATE_MODIFIED, FDP->ConsumeIntegral<int64_t>());
165 value.Put(Media::AppUriPermissionColumn::SOURCE_TOKENID, FDP->ConsumeIntegral<int64_t>());
166 value.Put(Media::AppUriPermissionColumn::TARGET_TOKENID, FDP->ConsumeIntegral<int64_t>());
167 dataShareValues.push_back(value);
168 }
169 Media::MediaLibraryCommand cmd(Media::OperationObject::MEDIA_APP_URI_PERMISSION, Media::OperationType::CREATE,
170 Media::MediaLibraryApi::API_10);
171 std::string funcName = FDP->ConsumeBytesAsString(NUM_BYTES);
172 std::shared_ptr<Media::TransactionOperations> trans = std::make_shared<Media::TransactionOperations>(funcName);
173 Media::MediaLibraryAppUriPermissionOperations::BatchInsertInner(cmd, dataShareValues, trans);
174 }
175
AppUriPermissionOperationsFuzzer()176 static void AppUriPermissionOperationsFuzzer()
177 {
178 string photoId = FDP->ConsumeBytesAsString(NUM_BYTES);
179 int32_t fileId = InsertPhotoAsset(photoId);
180 string appId = FDP->ConsumeBytesAsString(NUM_BYTES);
181 int32_t permissionType = FuzzPermissionType();
182 int32_t uriType = FuzzUriType();
183 HandleInsertOperationFuzzer(appId, fileId, permissionType, uriType);
184 permissionType = FuzzPermissionType();
185 HandleInsertOperationFuzzer(appId, fileId, permissionType, uriType); // if exit, run UpdatePermissionType();
186 DeleteOperationFuzzer(appId, fileId, permissionType);
187
188 BatchInsertFuzzer();
189 BatchInsertInnerFuzzer();
190 }
191
SetTables()192 void SetTables()
193 {
194 vector<string> createTableSqlList = {
195 Media::PhotoColumn::CREATE_PHOTO_TABLE,
196 Media::AppUriPermissionColumn::CREATE_APP_URI_PERMISSION_TABLE,
197 Media::AppUriSensitiveColumn::CREATE_APP_URI_SENSITIVE_TABLE,
198 };
199 for (auto &createTableSql : createTableSqlList) {
200 int32_t ret = g_rdbStore->ExecuteSql(createTableSql);
201 if (ret != NativeRdb::E_OK) {
202 MEDIA_ERR_LOG("Execute sql %{private}s failed", createTableSql.c_str());
203 return;
204 }
205 MEDIA_DEBUG_LOG("Execute sql %{private}s success", createTableSql.c_str());
206 }
207 }
208
Init()209 static void Init()
210 {
211 auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
212 auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
213 abilityContextImpl->SetStageContext(stageContext);
214 int32_t sceneCode = 0;
215 auto ret = Media::MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl,
216 abilityContextImpl, sceneCode);
217 CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "InitMediaLibraryMgr failed, ret: %{public}d", ret);
218
219 auto rdbStore = Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
220 if (rdbStore == nullptr) {
221 MEDIA_ERR_LOG("rdbStore is nullptr");
222 return;
223 }
224 g_rdbStore = rdbStore;
225 SetTables();
226 }
227
ClearKvStore()228 static inline void ClearKvStore()
229 {
230 Media::MediaLibraryKvStoreManager::GetInstance().CloseAllKvStore();
231 }
232 } // namespace OHOS
233
LLVMFuzzerInitialize(int * argc,char *** argv)234 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
235 {
236 OHOS::Init();
237 return 0;
238 }
239
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)240 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
241 {
242 FuzzedDataProvider fdp(data, size);
243 OHOS::FDP = &fdp;
244 if (data == nullptr) {
245 return 0;
246 }
247 OHOS::AppUriPermissionOperationsFuzzer();
248 OHOS::ClearKvStore();
249 return 0;
250 }
251