• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "medialibrarypermission_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 "media_log.h"
25 #include "medialibrary_data_manager.h"
26 #include "medialibrary_errno.h"
27 #include "medialibrary_unistore_manager.h"
28 #include "medialibrary_kvstore_manager.h"
29 #include "media_app_uri_permission_column.h"
30 #include "media_composite_permission_check.h"
31 #include "media_read_permission_check.h"
32 #include "media_write_permission_check.h"
33 
34 namespace OHOS {
35 namespace Media {
36 using namespace std;
37 static const int32_t NUM_BYTES = 1;
38 static const int32_t DEFAULT_CALLING_UID = 1;
39 static const int32_t DEFAULT_BUSINESS_CODE = 1;
40 static const int32_t USER_ID = -1;
41 static const int32_t MAX_URI_TYPE = 1;
42 static const int32_t MAX_PERMISSION_TYPE = 5;
43 std::shared_ptr<Media::MediaLibraryRdbStore> g_rdbStore;
44 FuzzedDataProvider *provider;
45 
46 static const string SQL_INSERT_URIPERMISSION =
47     "INSERT INTO UriPermission (target_tokenId, file_id, uri_type, permission_type)";
48 static const string VALUES_END = ") ";
49 
MockIsCalledBySelf()50 bool MockIsCalledBySelf()
51 {
52     return provider->ConsumeBool();
53 }
54 
MockGetCallingUid()55 pid_t MockGetCallingUid()
56 {
57     uint8_t data = provider->ConsumeIntegralInRange<uint8_t>(0, CALLING_UID_LIST.size() - DEFAULT_CALLING_UID);
58     return CALLING_UID_LIST[data];
59 }
60 
FuzzUriType()61 static int FuzzUriType()
62 {
63     vector<int> vecUriType;
64     vecUriType.assign(Media::AppUriPermissionColumn::URI_TYPES_ALL.begin(),
65         Media::AppUriPermissionColumn::URI_TYPES_ALL.end());
66     uint8_t data = provider->ConsumeIntegralInRange<uint8_t>(0, MAX_URI_TYPE);
67     return vecUriType[data];
68 }
69 
FuzzMediaLibraryBusinessCode()70 static inline MediaLibraryBusinessCode FuzzMediaLibraryBusinessCode()
71 {
72     uint8_t data = provider->ConsumeIntegralInRange<uint8_t>(0, BUSINESS_CODE_LIST.size() - DEFAULT_BUSINESS_CODE);
73     return static_cast<MediaLibraryBusinessCode>(data);
74 }
75 
FuzzPermissionType()76 static int FuzzPermissionType()
77 {
78     vector<int> vecPermissionType;
79     vecPermissionType.assign(AppUriPermissionColumn::PERMISSION_TYPES_ALL.begin(),
80         AppUriPermissionColumn::PERMISSION_TYPES_ALL.end());
81     uint8_t data = provider->ConsumeIntegralInRange<uint8_t>(0, MAX_PERMISSION_TYPE);
82     return vecPermissionType[data];
83 }
84 
InsertUriPermissionRecord(const uint32_t & tokenId,const int32_t & fileId,const int32_t & uriType,const int32_t & permissionType)85 static void InsertUriPermissionRecord(
86     const uint32_t &tokenId, const int32_t &fileId, const int32_t &uriType, const int32_t &permissionType)
87 {
88     if (g_rdbStore == nullptr) {
89         MEDIA_ERR_LOG("g_rdbStore is null.");
90         return;
91     }
92     std::string insertSql = SQL_INSERT_URIPERMISSION + " VALUES (" + to_string(tokenId) + "," + to_string(fileId) +
93                             "," + to_string(uriType) + "," + to_string(permissionType) + VALUES_END;
94     int32_t ret = g_rdbStore->ExecuteSql(insertSql);
95     if (ret != NativeRdb::E_OK) {
96         MEDIA_ERR_LOG("Execute sql %{public}s failed", insertSql.c_str());
97         return;
98     }
99     MEDIA_INFO_LOG("Execute sql %{public}s success", insertSql.c_str());
100 }
101 
102 static std::unordered_map<uint32_t, std::vector<std::vector<PermissionType>>> testMap = {
103     {1, {{PRIVATE_PERM}}},
104     {2, {{CLOUDFILE_SYNC}}},
105     {3, {{READ_PERM}}},
106     {4, {{WRITE_PERM}}},
107     {5, {{SYSTEMAPI_PERM}, {}}},
108     {6, {{}, {SYSTEMAPI_PERM}}},
109     {7, {}},
110     {8, {{PRIVATE_PERM, CLOUDFILE_SYNC, READ_PERM, WRITE_PERM}}},
111     {9, {{CLOUD_READ}, {CLOUD_WRITE}}},
112     {0, {{READ_PERM}, {WRITE_PERM}}},
113     {static_cast<uint32_t>(MediaLibraryBusinessCode::PAH_OPEN), {{READ_PERM, WRITE_PERM}}},  // openfile api
114 };
115 
GetTestPermissionPolicy(uint32_t code,std::vector<std::vector<PermissionType>> & permissionPolicy)116 static int32_t GetTestPermissionPolicy(uint32_t code, std::vector<std::vector<PermissionType>> &permissionPolicy)
117 {
118     auto it = testMap.find(code);
119     if (it != testMap.end()) {
120         permissionPolicy = it->second;
121         return E_SUCCESS;
122     }
123     return E_FAIL;
124 }
125 
PreparePermissionParam(uint32_t code,int32_t userId,bool isDBBypass,std::unordered_map<std::string,std::string> & headerMap,PermissionHeaderReq & data)126 static int32_t PreparePermissionParam(uint32_t code, int32_t userId, bool isDBBypass,
127     std::unordered_map<std::string, std::string> &headerMap, PermissionHeaderReq &data)
128 {
129     std::vector<std::vector<PermissionType>> permissionPolicy;
130     if (GetTestPermissionPolicy(code, permissionPolicy) != E_SUCCESS) {
131         return E_FAIL;
132     }
133     data = PermissionHeaderReq::convertToPermissionHeaderReq(headerMap, userId, permissionPolicy, isDBBypass);
134     return E_SUCCESS;
135 }
136 
ReadPermissionCheckTest()137 static void ReadPermissionCheckTest()
138 {
139     MEDIA_INFO_LOG("ReadPermissionCheckTest enter");
140     uint32_t businessCode = static_cast<uint32_t>(FuzzMediaLibraryBusinessCode());
141 
142     uint32_t tokenId = PermissionUtils::GetTokenId();
143     int32_t permissionType = static_cast<int32_t>(FuzzPermissionType());
144     int32_t fileId = provider->ConsumeIntegral<int32_t>();
145     int32_t uriType = static_cast<int32_t>(FuzzUriType());
146     InsertUriPermissionRecord(tokenId, fileId, uriType, permissionType);
147     PermissionHeaderReq data;
148     std::unordered_map<std::string, std::string> headerMap;
149     if (provider->ConsumeBool()) {
150         headerMap = {
151             {PermissionHeaderReq::FILE_ID_KEY, to_string(fileId)},
152             {PermissionHeaderReq::URI_TYPE_KEY, to_string(uriType)},
153             {PermissionHeaderReq::OPEN_URI_KEY, provider->ConsumeBytesAsString(NUM_BYTES)},
154             {PermissionHeaderReq::OPEN_MODE_KEY, "rw"}
155         };
156     }
157     int32_t userId = provider->ConsumeBool() ? USER_ID : provider->ConsumeIntegral<int32_t>();
158     PreparePermissionParam(businessCode, userId, provider->ConsumeBool(), headerMap, data);
159 
160     auto readCompositePermCheck = make_shared<ReadCompositePermCheck>();
161     CHECK_AND_RETURN_LOG(readCompositePermCheck != nullptr, "readCompositePermCheck is nullptr");
162     shared_ptr<PermissionCheck> check = make_shared<CompositePermissionCheck>();
163     readCompositePermCheck->AddCheck(check);
164     readCompositePermCheck->CheckPermission(businessCode, data);
165 
166     auto readPrivilegePermCheck = make_shared<ReadPrivilegePermCheck>();
167     CHECK_AND_RETURN_LOG(readPrivilegePermCheck != nullptr, "readPrivilegePermCheck is nullptr");
168     readPrivilegePermCheck->CheckPermission(businessCode, data);
169 
170     auto dbReadPermCheck = make_shared<DbReadPermCheck>();
171     CHECK_AND_RETURN_LOG(dbReadPermCheck != nullptr, "dbReadPermCheck is nullptr");
172     dbReadPermCheck->CheckPermission(businessCode, data);
173 
174     auto grantReadPermCheck = make_shared<GrantReadPermCheck>();
175     CHECK_AND_RETURN_LOG(grantReadPermCheck != nullptr, "grantReadPermCheck is nullptr");
176     grantReadPermCheck->CheckPermission(businessCode, data);
177 
178     auto mediaToolReadPermCheck = make_shared<MediaToolReadPermCheck>();
179     CHECK_AND_RETURN_LOG(mediaToolReadPermCheck != nullptr, "mediaToolReadPermCheck is nullptr");
180     mediaToolReadPermCheck->CheckPermission(businessCode, data);
181 
182     auto deprecatedReadPermCheck = make_shared<DeprecatedReadPermCheck>();
183     CHECK_AND_RETURN_LOG(deprecatedReadPermCheck != nullptr, "deprecatedReadPermCheck is nullptr");
184     deprecatedReadPermCheck->CheckPermission(businessCode, data);
185     MEDIA_INFO_LOG("ReadPermissionCheckTest end");
186 }
187 
WritePermissionCheckTest()188 static void WritePermissionCheckTest()
189 {
190     MEDIA_INFO_LOG("WritePermissionCheckTest enter");
191     uint32_t businessCode = static_cast<uint32_t>(FuzzMediaLibraryBusinessCode());
192 
193     uint32_t tokenId = PermissionUtils::GetTokenId();
194     int32_t permissionType = static_cast<int32_t>(FuzzPermissionType());
195     int32_t fileId = provider->ConsumeIntegral<int32_t>();
196     int32_t uriType = static_cast<int32_t>(FuzzUriType());
197     InsertUriPermissionRecord(tokenId, fileId, uriType, permissionType);
198     PermissionHeaderReq data;
199     std::unordered_map<std::string, std::string> headerMap;
200     if (provider->ConsumeBool()) {
201         headerMap = {
202             {PermissionHeaderReq::FILE_ID_KEY, to_string(fileId)},
203             {PermissionHeaderReq::URI_TYPE_KEY, to_string(uriType)},
204             {PermissionHeaderReq::OPEN_URI_KEY, provider->ConsumeBytesAsString(NUM_BYTES)},
205             {PermissionHeaderReq::OPEN_MODE_KEY, "rw"}
206         };
207     }
208     int32_t userId = provider->ConsumeBool() ? USER_ID : provider->ConsumeIntegral<int32_t>();
209     PreparePermissionParam(businessCode, userId, provider->ConsumeBool(), headerMap, data);
210 
211     auto writeCompositePermCheck = make_shared<WriteCompositePermCheck>();
212     CHECK_AND_RETURN_LOG(writeCompositePermCheck != nullptr, "writeCompositePermCheck is nullptr");
213     shared_ptr<PermissionCheck> check = make_shared<CompositePermissionCheck>();
214     writeCompositePermCheck->AddCheck(check);
215     writeCompositePermCheck->CheckPermission(businessCode, data);
216 
217     auto writePrivilegePermCheck = make_shared<WritePrivilegePermCheck>();
218     CHECK_AND_RETURN_LOG(writePrivilegePermCheck != nullptr, "writePrivilegePermCheck is nullptr");
219     writePrivilegePermCheck->CheckPermission(businessCode, data);
220 
221     auto dbWritePermCheck = make_shared<DbWritePermCheck>();
222     CHECK_AND_RETURN_LOG(dbWritePermCheck != nullptr, "dbWritePermCheck is nullptr");
223     dbWritePermCheck->CheckPermission(businessCode, data);
224 
225     auto grantWritePermCheck = make_shared<GrantWritePermCheck>();
226     CHECK_AND_RETURN_LOG(grantWritePermCheck != nullptr, "grantWritePermCheck is nullptr");
227     grantWritePermCheck->CheckPermission(businessCode, data);
228 
229     auto mediaToolWritePermCheck = make_shared<MediaToolWritePermCheck>();
230     CHECK_AND_RETURN_LOG(mediaToolWritePermCheck != nullptr, "mediaToolWritePermCheck is nullptr");
231     mediaToolWritePermCheck->CheckPermission(businessCode, data);
232 
233     auto securityComponentPermCheck = make_shared<SecurityComponentPermCheck>();
234     CHECK_AND_RETURN_LOG(securityComponentPermCheck != nullptr, "securityComponentPermCheck is nullptr");
235     securityComponentPermCheck->CheckPermission(businessCode, data);
236 
237     auto deprecatedWritePermCheck = make_shared<DeprecatedWritePermCheck>();
238     CHECK_AND_RETURN_LOG(deprecatedWritePermCheck != nullptr, "deprecatedWritePermCheck is nullptr");
239     deprecatedWritePermCheck->CheckPermission(businessCode, data);
240 
241     auto shortTermWritePermCheck = make_shared<ShortTermWritePermCheck>();
242     CHECK_AND_RETURN_LOG(shortTermWritePermCheck != nullptr, "shortTermWritePermCheck is nullptr");
243     shortTermWritePermCheck->CheckPermission(businessCode, data);
244     MEDIA_INFO_LOG("WritePermissionCheckTest end");
245 }
246 
SetTables()247 void SetTables()
248 {
249     vector<string> createTableSqlList = {
250         AppUriPermissionColumn::CREATE_APP_URI_PERMISSION_TABLE
251     };
252     for (auto &createTableSql : createTableSqlList) {
253         int32_t ret = g_rdbStore->ExecuteSql(createTableSql);
254         if (ret != NativeRdb::E_OK) {
255             MEDIA_ERR_LOG("Execute sql %{private}s failed", createTableSql.c_str());
256             return;
257         }
258         MEDIA_DEBUG_LOG("Execute sql %{private}s success", createTableSql.c_str());
259     }
260 }
261 
Init()262 static void Init()
263 {
264     auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
265     auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
266     abilityContextImpl->SetStageContext(stageContext);
267     int32_t sceneCode = 0;
268     auto ret = Media::MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl,
269         abilityContextImpl, sceneCode);
270     CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "InitMediaLibraryMgr failed, ret: %{public}d", ret);
271 
272     auto rdbStore = Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
273     if (rdbStore == nullptr) {
274         MEDIA_ERR_LOG("rdbStore is nullptr");
275         return;
276     }
277     g_rdbStore = rdbStore;
278     SetTables();
279 }
280 
ClearKvStore()281 static inline void ClearKvStore()
282 {
283     Media::MediaLibraryKvStoreManager::GetInstance().CloseAllKvStore();
284 }
285 } //namespace Media
286 } // namespace OHOS
287 
LLVMFuzzerInitialize(int * argc,char *** argv)288 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
289 {
290     OHOS::Media::Init();
291     return 0;
292 }
293 
294 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)295 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
296 {
297     FuzzedDataProvider provider(data, size);
298     OHOS::Media::provider = &provider;
299     if (data == nullptr) {
300         return 0;
301     }
302     OHOS::Media::isCalledBySelfPtr = OHOS::Media::MockIsCalledBySelf;
303     OHOS::Media::getCallingUidPtr = OHOS::Media::MockGetCallingUid;
304     OHOS::Media::ReadPermissionCheckTest();
305     OHOS::Media::WritePermissionCheckTest();
306     OHOS::Media::ClearKvStore();
307     return 0;
308 }