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 "medialibraryurisensitiveoperations_fuzzer.h"
17
18 #include <cstdint>
19 #include <string>
20 #include <vector>
21
22 #include "ability_context_impl.h"
23 #include "medialibrary_urisensitive_operations.h"
24 #include "medialibrary_app_uri_permission_operations.h"
25 #include "medialibrary_app_uri_sensitive_operations.h"
26 #include "datashare_predicates.h"
27 #include "media_app_uri_permission_column.h"
28 #include "media_app_uri_sensitive_column.h"
29 #include "media_column.h"
30 #include "media_log.h"
31 #include "medialibrary_command.h"
32 #include "medialibrary_data_manager.h"
33 #include "medialibrary_errno.h"
34 #include "medialibrary_operation.h"
35 #include "medialibrary_photo_operations.h"
36 #include "medialibrary_unistore.h"
37 #include "medialibrary_unistore_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 SENSITIVE_DEFAULT = -1;
48 const int32_t URI_DEFAULT = 0;
49 const int32_t BATCH_INSERT_NUMBER = 5;
50 std::shared_ptr<Media::MediaLibraryRdbStore> g_rdbStore;
FuzzInt32(const uint8_t * data,size_t size)51 static inline int32_t FuzzInt32(const uint8_t *data, size_t size)
52 {
53 if (data == nullptr || size < sizeof(int32_t)) {
54 return 0;
55 }
56 return static_cast<int32_t>(*data);
57 }
58
FuzzString(const uint8_t * data,size_t size)59 static inline string FuzzString(const uint8_t *data, size_t size)
60 {
61 return {reinterpret_cast<const char*>(data), size};
62 }
63
FuzzUriType(const uint8_t * data,size_t size)64 static int FuzzUriType(const uint8_t *data, size_t size)
65 {
66 vector<int> vecUriType;
67 vecUriType.assign(Media::AppUriSensitiveColumn::URI_TYPES_ALL.begin(),
68 Media::AppUriSensitiveColumn::URI_TYPES_ALL.end());
69 vecUriType.push_back(URI_DEFAULT);
70 uint8_t length = static_cast<uint8_t>(vecUriType.size());
71 if (*data < length) {
72 return vecUriType[*data];
73 }
74 return Media::AppUriSensitiveColumn::URI_PHOTO;
75 }
76
FuzzPermissionType(const uint8_t * data,size_t size)77 static int FuzzPermissionType(const uint8_t *data, size_t size)
78 {
79 vector<int> vecPermissionType;
80 vecPermissionType.assign(Media::AppUriPermissionColumn::PERMISSION_TYPES_ALL.begin(),
81 Media::AppUriPermissionColumn::PERMISSION_TYPES_ALL.end());
82 vecPermissionType.push_back(PERMISSION_DEFAULT);
83 uint8_t length = static_cast<uint8_t>(vecPermissionType.size());
84 if (*data < length) {
85 return vecPermissionType[*data];
86 }
87 return Media::AppUriPermissionColumn::PERMISSION_TEMPORARY_READ;
88 }
89
FuzzHideSensitiveType(const uint8_t * data,size_t size)90 static int FuzzHideSensitiveType(const uint8_t *data, size_t size)
91 {
92 vector<int> vecHideSensitiveType;
93 vecHideSensitiveType.assign(Media::AppUriSensitiveColumn::SENSITIVE_TYPES_ALL.begin(),
94 Media::AppUriSensitiveColumn::SENSITIVE_TYPES_ALL.end());
95 vecHideSensitiveType.push_back(SENSITIVE_DEFAULT);
96 uint8_t length = static_cast<uint8_t>(vecHideSensitiveType.size());
97 if (*data < length) {
98 return vecHideSensitiveType[*data];
99 }
100 return Media::AppUriSensitiveColumn::SENSITIVE_ALL_DESENSITIZE;
101 }
102
InsertOperationFuzzer(string appId,int32_t photoId,int32_t sensitiveType,int32_t uriType)103 static void InsertOperationFuzzer(string appId, int32_t photoId, int32_t sensitiveType, int32_t uriType)
104 {
105 DataShareValuesBucket values;
106 values.Put(Media::AppUriSensitiveColumn::APP_ID, appId);
107 values.Put(Media::AppUriSensitiveColumn::FILE_ID, photoId);
108 values.Put(Media::AppUriSensitiveColumn::HIDE_SENSITIVE_TYPE, sensitiveType);
109 values.Put(Media::AppUriSensitiveColumn::URI_TYPE, uriType);
110
111 Media::MediaLibraryCommand cmd(Media::OperationObject::APP_URI_PERMISSION_INNER, Media::OperationType::CREATE,
112 Media::MediaLibraryApi::API_10);
113 NativeRdb::ValuesBucket rdbValue = RdbDataShareAdapter::RdbUtils::ToValuesBucket(values);
114 cmd.SetValueBucket(rdbValue);
115 Media::UriSensitiveOperations::InsertOperation(cmd);
116 }
117
DeleteOperationFuzzer(string appId,int32_t photoId)118 static void DeleteOperationFuzzer(string appId, int32_t photoId)
119 {
120 DataShare::DataSharePredicates dataSharePredicate;
121 dataSharePredicate.And()->EqualTo(Media::AppUriSensitiveColumn::APP_ID, appId);
122 dataSharePredicate.And()->EqualTo(Media::AppUriSensitiveColumn::FILE_ID, photoId);
123 Media::MediaLibraryCommand cmd(Media::OperationObject::APP_URI_PERMISSION_INNER, Media::OperationType::DELETE,
124 Media::MediaLibraryApi::API_10);
125 cmd.SetTableName(Media::AppUriSensitiveColumn::APP_URI_SENSITIVE_TABLE);
126 NativeRdb::RdbPredicates rdbPredicate = RdbDataShareAdapter::RdbUtils::ToPredicates(dataSharePredicate,
127 Media::AppUriSensitiveColumn::APP_URI_SENSITIVE_TABLE);
128 cmd.SetDataSharePred(dataSharePredicate);
129 cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
130 cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
131 Media::UriSensitiveOperations::DeleteOperation(cmd);
132 }
133
BatchInsertFuzzer(const uint8_t * data,size_t size)134 static void BatchInsertFuzzer(const uint8_t* data, size_t size)
135 {
136 vector<DataShare::DataShareValuesBucket> dataShareValues;
137 for (int32_t i = 0; i < BATCH_INSERT_NUMBER; i++) {
138 DataShareValuesBucket value;
139 int32_t photoId = FuzzInt32(data, size);
140 value.Put(Media::AppUriSensitiveColumn::APP_ID, FuzzString(data, size));
141 value.Put(Media::AppUriSensitiveColumn::FILE_ID, photoId);
142 value.Put(Media::AppUriSensitiveColumn::HIDE_SENSITIVE_TYPE, FuzzHideSensitiveType(data, size));
143 value.Put(Media::AppUriPermissionColumn::PERMISSION_TYPE, FuzzPermissionType(data, size));
144 value.Put(Media::AppUriSensitiveColumn::URI_TYPE, FuzzUriType(data, size));
145 value.Put(Media::AppUriSensitiveColumn::SOURCE_TOKENID, FuzzInt32(data, size));
146 value.Put(Media::AppUriSensitiveColumn::TARGET_TOKENID, FuzzInt32(data, size));
147 dataShareValues.push_back(value);
148 }
149 Media::MediaLibraryCommand cmd(Media::OperationObject::APP_URI_PERMISSION_INNER, Media::OperationType::CREATE,
150 Media::MediaLibraryApi::API_10);
151 Media::UriSensitiveOperations::GrantUriSensitive(cmd, dataShareValues);
152 }
153
QuerySensitiveTypeFuzzer(const uint8_t * data,size_t size)154 static void QuerySensitiveTypeFuzzer(const uint8_t* data, size_t size)
155 {
156 uint32_t tokenId = FuzzInt32(data, size);
157 std::string fileId = FuzzString(data, size);
158 Media::UriSensitiveOperations::QuerySensitiveType(tokenId, fileId);
159 }
160
QueryForceSensitiveFuzzer(const uint8_t * data,size_t size)161 static void QueryForceSensitiveFuzzer(const uint8_t* data, size_t size)
162 {
163 uint32_t tokenId = FuzzInt32(data, size);
164 std::string fileId = FuzzString(data, size);
165 Media::UriSensitiveOperations::QueryForceSensitive(tokenId, fileId);
166 }
167
UriSensitiveOperationsFuzzer(const uint8_t * data,size_t size)168 static void UriSensitiveOperationsFuzzer(const uint8_t* data, size_t size)
169 {
170 int32_t photoId = FuzzInt32(data, size);
171 string appId = FuzzString(data, size);
172 int32_t sensitiveType = FuzzHideSensitiveType(data, size);
173 int32_t uriType = FuzzUriType(data, size);
174
175 InsertOperationFuzzer(appId, photoId, sensitiveType, uriType);
176 DeleteOperationFuzzer(appId, photoId);
177 BatchInsertFuzzer(data, size);
178 QuerySensitiveTypeFuzzer(data, size);
179 QueryForceSensitiveFuzzer(data, size);
180 }
181
SetTables()182 void SetTables()
183 {
184 vector<string> createTableSqlList = {
185 Media::PhotoColumn::CREATE_PHOTO_TABLE,
186 Media::AppUriPermissionColumn::CREATE_APP_URI_PERMISSION_TABLE,
187 Media::AppUriSensitiveColumn::CREATE_APP_URI_SENSITIVE_TABLE,
188 };
189 for (auto &createTableSql : createTableSqlList) {
190 int32_t ret = g_rdbStore->ExecuteSql(createTableSql);
191 if (ret != NativeRdb::E_OK) {
192 MEDIA_ERR_LOG("Execute sql %{private}s failed", createTableSql.c_str());
193 return;
194 }
195 MEDIA_DEBUG_LOG("Execute sql %{private}s success", createTableSql.c_str());
196 }
197 }
198
Init()199 static void Init()
200 {
201 auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
202 auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
203 abilityContextImpl->SetStageContext(stageContext);
204 int32_t sceneCode = 0;
205 auto ret = Media::MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl,
206 abilityContextImpl, sceneCode);
207 CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "InitMediaLibraryMgr failed, ret: %{public}d", ret);
208
209 auto rdbStore = Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
210 if (rdbStore == nullptr) {
211 MEDIA_ERR_LOG("rdbStore is nullptr");
212 return;
213 }
214 g_rdbStore = rdbStore;
215 SetTables();
216 }
217 } // namespace OHOS
218
LLVMFuzzerInitialize(int * argc,char *** argv)219 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
220 {
221 OHOS::Init();
222 return 0;
223 }
224
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)225 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
226 {
227 OHOS::UriSensitiveOperationsFuzzer(data, size);
228 return 0;
229 }
230