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 "permission_utils.h" 16 17#include <unordered_set> 18 19#include "access_token.h" 20#include "accesstoken_kit.h" 21#include "el5_filekey_manager_kit.h" 22#include "ipc_skeleton.h" 23#include "iservice_registry.h" 24#include "media_file_utils.h" 25#include "media_log.h" 26#include "medialibrary_db_const.h" 27#include "medialibrary_errno.h" 28#include "medialibrary_tracer.h" 29#include "privacy_kit.h" 30#include "system_ability_definition.h" 31#include "tokenid_kit.h" 32 33namespace OHOS { 34namespace Media { 35using namespace std; 36using namespace OHOS::Security::AccessToken; 37using namespace OHOS::AppExecFwk::Constants; 38 39const int32_t CAPACITY = 50; 40const int32_t HDC_SHELL_UID = 2000; 41const int32_t BASE_USER_RANGE = 200000; 42 43std::mutex PermissionUtils::uninstallMutex_; 44std::list<std::pair<int32_t, BundleInfo>> PermissionUtils::bundleInfoList_ = {}; 45std::unordered_map<int32_t, std::list<std::pair<int32_t, BundleInfo>>::iterator> PermissionUtils::bundleInfoMap_ = {}; 46 47bool g_isDelayTask; 48std::mutex addPhotoPermissionRecordLock_; 49std::thread delayTask_; 50std::vector<Security::AccessToken::AddPermParamInfo> infos_; 51 52sptr<AppExecFwk::IBundleMgr> PermissionUtils::bundleMgr_ = nullptr; 53mutex PermissionUtils::bundleMgrMutex_; 54sptr<AppExecFwk::IBundleMgr> PermissionUtils::GetSysBundleManager() 55{ 56 if (bundleMgr_ != nullptr) { 57 return bundleMgr_; 58 } 59 60 lock_guard<mutex> lock(bundleMgrMutex_); 61 if (bundleMgr_ != nullptr) { 62 return bundleMgr_; 63 } 64 65 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 66 if (systemAbilityMgr == nullptr) { 67 MEDIA_ERR_LOG("Failed to get SystemAbilityManager."); 68 return nullptr; 69 } 70 71 auto bundleObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 72 if (bundleObj == nullptr) { 73 MEDIA_ERR_LOG("Remote object is nullptr."); 74 return nullptr; 75 } 76 77 auto bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(bundleObj); 78 if (bundleMgr == nullptr) { 79 MEDIA_ERR_LOG("Failed to iface_cast"); 80 return nullptr; 81 } 82 bundleMgr_ = bundleMgr; 83 84 return bundleMgr_; 85} 86 87void PermissionUtils::GetBundleNameFromCache(int uid, string &bundleName) 88{ 89 lock_guard<mutex> lock(uninstallMutex_); 90 auto iter = bundleInfoMap_.find(uid); 91 if (iter != bundleInfoMap_.end() && !iter->second->second.bundleName.empty()) { 92 bundleInfoList_.splice(bundleInfoList_.begin(), bundleInfoList_, iter->second); 93 bundleName = iter->second->second.bundleName; 94 return; 95 } 96 bundleMgr_ = GetSysBundleManager(); 97 if (bundleMgr_ == nullptr) { 98 bundleName = ""; 99 return; 100 } 101 auto result = bundleMgr_->GetBundleNameForUid(uid, bundleName); 102 if (!result) { 103 bundleName = ""; 104 return; 105 } 106 107 UpdateBundleNameInCache(uid, bundleName); 108} 109 110void PermissionUtils::GetPackageNameFromCache(int uid, const string &bundleName, string &packageName) 111{ 112 lock_guard<mutex> lock(uninstallMutex_); 113 auto iter = bundleInfoMap_.find(uid); 114 if (iter != bundleInfoMap_.end() && !iter->second->second.packageName.empty()) { 115 bundleInfoList_.splice(bundleInfoList_.begin(), bundleInfoList_, iter->second); 116 packageName = iter->second->second.packageName; 117 return; 118 } 119 120 int32_t userId = uid / BASE_USER_RANGE; 121 MEDIA_DEBUG_LOG("uid:%{private}d, userId:%{private}d", uid, userId); 122 123 AAFwk::Want want; 124 auto bundleMgr = GetSysBundleManager(); 125 if (bundleMgr == nullptr) { 126 MEDIA_ERR_LOG("Get BundleManager failed"); 127 packageName = ""; 128 return; 129 } 130 int ret = bundleMgr->GetLaunchWantForBundle(bundleName, want, userId); 131 if (ret != ERR_OK) { 132 MEDIA_ERR_LOG("Can not get bundleName by want, err=%{public}d, userId=%{private}d", ret, userId); 133 packageName = ""; 134 return; 135 } 136 string abilityName = want.GetOperation().GetAbilityName(); 137 packageName = bundleMgr->GetAbilityLabel(bundleName, abilityName); 138 139 UpdatePackageNameInCache(uid, packageName); 140} 141 142void PermissionUtils::GetAppIdFromCache(int uid, const string &bundleName, string &appId) 143{ 144 lock_guard<mutex> lock(uninstallMutex_); 145 auto iter = bundleInfoMap_.find(uid); 146 if (iter != bundleInfoMap_.end() && !iter->second->second.appId.empty()) { 147 bundleInfoList_.splice(bundleInfoList_.begin(), bundleInfoList_, iter->second); 148 appId = iter->second->second.appId; 149 return; 150 } 151 int32_t userId = uid / BASE_USER_RANGE; 152 MEDIA_DEBUG_LOG("uid:%{private}d, userId:%{private}d", uid, userId); 153 154 auto bundleMgr_ = GetSysBundleManager(); 155 if (bundleMgr_ == nullptr) { 156 MEDIA_ERR_LOG("Get BundleManager failed"); 157 return; 158 } 159 160 appId = bundleMgr_->GetAppIdByBundleName(bundleName, userId); 161 162 UpdateAppIdInCache(uid, appId); 163} 164 165void PermissionUtils::UpdateLatestBundleInfo(int uid, const BundleInfo &bundleInfo) 166{ 167 auto iter = bundleInfoMap_.find(uid); 168 if (iter != bundleInfoMap_.end()) { 169 bundleInfoList_.erase(iter->second); 170 } 171 bundleInfoList_.push_front(make_pair(uid, bundleInfo)); 172 bundleInfoMap_[uid] = bundleInfoList_.begin(); 173 if (bundleInfoMap_.size() > CAPACITY) { 174 int32_t deleteKey = bundleInfoList_.back().first; 175 bundleInfoMap_.erase(deleteKey); 176 bundleInfoList_.pop_back(); 177 } 178} 179 180void PermissionUtils::UpdateBundleNameInCache(int uid, const string &bundleName) 181{ 182 auto iter = bundleInfoMap_.find(uid); 183 if (iter != bundleInfoMap_.end()) { 184 BundleInfo bundleInfo = bundleInfoMap_[uid]->second; 185 bundleInfo.bundleName = bundleName; 186 UpdateLatestBundleInfo(uid, bundleInfo); 187 return; 188 } 189 BundleInfo bundleInfo { bundleName, "", "" }; 190 UpdateLatestBundleInfo(uid, bundleInfo); 191} 192 193void PermissionUtils::UpdatePackageNameInCache(int uid, const string &packageName) 194{ 195 auto iter = bundleInfoMap_.find(uid); 196 if (iter != bundleInfoMap_.end()) { 197 BundleInfo bundleInfo = bundleInfoMap_[uid]->second; 198 bundleInfo.packageName = packageName; 199 UpdateLatestBundleInfo(uid, bundleInfo); 200 return; 201 } 202 BundleInfo bundleInfo { "", packageName, "" }; 203 UpdateLatestBundleInfo(uid, bundleInfo); 204} 205 206void PermissionUtils::UpdateAppIdInCache(int uid, const string &appId) 207{ 208 BundleInfo bundleInfo { "", "", appId }; 209 auto iter = bundleInfoMap_.find(uid); 210 if (iter != bundleInfoMap_.end()) { 211 bundleInfo = bundleInfoMap_[uid]->second; 212 bundleInfo.appId = appId; 213 } 214 UpdateLatestBundleInfo(uid, bundleInfo); 215} 216 217void PermissionUtils::ClearBundleInfoInCache() 218{ 219 lock_guard<mutex> lock(uninstallMutex_); 220 bundleInfoMap_.clear(); 221 bundleInfoList_.clear(); 222 MEDIA_INFO_LOG("clear all info from cache"); 223} 224 225void PermissionUtils::GetClientBundle(const int uid, string &bundleName) 226{ 227 GetBundleNameFromCache(uid, bundleName); 228} 229 230void PermissionUtils::GetPackageName(const int uid, std::string &packageName) 231{ 232 packageName = ""; 233 string bundleName; 234 GetClientBundle(uid, bundleName); 235 if (bundleName.empty()) { 236 MEDIA_ERR_LOG("Get bundle name failed"); 237 return; 238 } 239 240 GetPackageNameFromCache(uid, bundleName, packageName); 241} 242 243bool inline ShouldAddPermissionRecord(const AccessTokenID &token) 244{ 245 return (AccessTokenKit::GetTokenTypeFlag(token) == TOKEN_HAP); 246} 247 248void AddPermissionRecord(const AccessTokenID &token, const string &perm, const bool permGranted) 249{ 250 if (!ShouldAddPermissionRecord(token)) { 251 return; 252 } 253 254 int res = PrivacyKit::AddPermissionUsedRecord(token, perm, !!permGranted, !permGranted, true); 255 if (res != 0) { 256 /* Failed to add permission used record, not fatal */ 257 MEDIA_WARN_LOG("Failed to add permission used record: %{public}s, permGranted: %{public}d, err: %{public}d", 258 perm.c_str(), permGranted, res); 259 } 260} 261 262vector<AddPermParamInfo> GetPermissionRecord() 263{ 264 lock_guard<mutex> lock(addPhotoPermissionRecordLock_); 265 vector<AddPermParamInfo> result = infos_; 266 infos_.clear(); 267 return result; 268} 269 270void AddPermissionRecord() 271{ 272 vector<AddPermParamInfo> infos = GetPermissionRecord(); 273 for (const auto &info : infos) { 274 int32_t ret = PrivacyKit::AddPermissionUsedRecord(info, true); 275 if (ret != 0) { 276 /* Failed to add permission used record, not fatal */ 277 MEDIA_WARN_LOG("Failed to add permission used record: %{public}s, permGranted: %{public}d, err: %{public}d", 278 info.permissionName.c_str(), info.successCount, ret); 279 } 280 MEDIA_DEBUG_LOG("Info: token = %{private}d, perm = %{private}s, permGranted = %{private}d, \ 281 !permGranted = %{private}d, type = %{public}d", info.tokenId, info.permissionName.c_str(), 282 info.successCount, info.failCount, info.type); 283 } 284 infos.clear(); 285} 286 287void DelayAddPermissionRecord() 288{ 289 string name("DelayAddPermissionRecord"); 290 pthread_setname_np(pthread_self(), name.c_str()); 291 MEDIA_INFO_LOG("DelayTask start"); 292 std::this_thread::sleep_for(std::chrono::seconds(1)); 293 AddPermissionRecord(); 294 g_isDelayTask = false; 295 MEDIA_INFO_LOG("DelayTask end"); 296} 297 298void DelayTaskInit() 299{ 300 if (!g_isDelayTask) { 301 MEDIA_INFO_LOG("DelayTaskInit"); 302 delayTask_ = thread(DelayAddPermissionRecord); 303 delayTask_.detach(); 304 g_isDelayTask = true; 305 } 306} 307 308void CollectPermissionRecord(const AccessTokenID &token, const string &perm, 309 const bool permGranted, const PermissionUsedType type) 310{ 311 lock_guard<mutex> lock(addPhotoPermissionRecordLock_); 312 DelayTaskInit(); 313 314 if (!ShouldAddPermissionRecord(token)) { 315 return; 316 } 317 318 AddPermParamInfo info = {token, perm, permGranted, !permGranted, type}; 319 auto iter = find_if(infos_.begin(), infos_.end(), [&token, &perm, type](auto &info) { 320 return info.tokenId == token && info.permissionName == perm && info.type == type; 321 }); 322 if (iter == infos_.end()) { 323 infos_.push_back(info); 324 } else if (permGranted) { 325 iter->successCount += 1; 326 } else if (!permGranted) { 327 iter->failCount += 1; 328 } 329} 330 331void PermissionUtils::CollectPermissionInfo(const string &permission, 332 const bool permGranted, const PermissionUsedType type) 333{ 334 AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); 335 CollectPermissionRecord(tokenCaller, permission, permGranted, type); 336} 337 338bool PermissionUtils::CheckPhotoCallerPermission(const string &permission) 339{ 340 PermissionUsedType type = PermissionUsedTypeValue::NORMAL_TYPE; 341 AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); 342 int res = AccessTokenKit::VerifyAccessToken(tokenCaller, permission); 343 if (res != PermissionState::PERMISSION_GRANTED) { 344 MEDIA_ERR_LOG("Have no media permission: %{public}s", permission.c_str()); 345 CollectPermissionRecord(tokenCaller, permission, false, type); 346 return false; 347 } 348 CollectPermissionRecord(tokenCaller, permission, true, type); 349 return true; 350} 351 352bool PermissionUtils::CheckPhotoCallerPermission(const vector<string> &perms) 353{ 354 if (perms.empty()) { 355 return false; 356 } 357 358 for (const auto &perm : perms) { 359 if (!CheckPhotoCallerPermission(perm)) { 360 return false; 361 } 362 } 363 return true; 364} 365 366bool PermissionUtils::CheckCallerPermission(const string &permission) 367{ 368 MediaLibraryTracer tracer; 369 tracer.Start("CheckCallerPermission"); 370 371 AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); 372 int res = AccessTokenKit::VerifyAccessToken(tokenCaller, permission); 373 if (res != PermissionState::PERMISSION_GRANTED) { 374 MEDIA_ERR_LOG("Have no media permission: %{public}s", permission.c_str()); 375 AddPermissionRecord(tokenCaller, permission, false); 376 return false; 377 } 378 AddPermissionRecord(tokenCaller, permission, true); 379 380 return true; 381} 382 383/* Check whether caller has at least one of @perms */ 384bool PermissionUtils::CheckHasPermission(const vector<string> &perms) 385{ 386 if (perms.empty()) { 387 return false; 388 } 389 390 for (const auto &perm : perms) { 391 if (CheckCallerPermission(perm)) { 392 return true; 393 } 394 } 395 396 return false; 397} 398 399/* Check whether caller has all the @perms */ 400bool PermissionUtils::CheckCallerPermission(const vector<string> &perms) 401{ 402 if (perms.empty()) { 403 return false; 404 } 405 406 for (const auto &perm : perms) { 407 if (!CheckCallerPermission(perm)) { 408 return false; 409 } 410 } 411 return true; 412} 413 414uint32_t PermissionUtils::GetTokenId() 415{ 416 return IPCSkeleton::GetCallingTokenID(); 417} 418 419bool PermissionUtils::IsSystemApp() 420{ 421 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID(); 422 return TokenIdKit::IsSystemAppByFullTokenID(tokenId); 423} 424 425bool PermissionUtils::CheckIsSystemAppByUid() 426{ 427 int uid = IPCSkeleton::GetCallingUid(); 428 bundleMgr_ = GetSysBundleManager(); 429 if (bundleMgr_ == nullptr) { 430 MEDIA_ERR_LOG("Can not get bundleMgr"); 431 return false; 432 } 433 return bundleMgr_->CheckIsSystemAppByUid(uid); 434} 435 436bool PermissionUtils::IsNativeSAApp() 437{ 438 uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); 439 ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId); 440 MEDIA_DEBUG_LOG("check if native sa token, tokenId:%{public}d, tokenType:%{public}d", 441 tokenId, tokenType); 442 if (tokenType == ATokenTypeEnum::TOKEN_NATIVE) { 443 return true; 444 } 445 return false; 446} 447 448bool PermissionUtils::IsRootShell() 449{ 450 return IPCSkeleton::GetCallingUid() == 0; 451} 452 453bool PermissionUtils::IsHdcShell() 454{ 455 return IPCSkeleton::GetCallingUid() == HDC_SHELL_UID; 456} 457 458string PermissionUtils::GetPackageNameByBundleName(const string &bundleName) 459{ 460 const static int32_t INVALID_UID = -1; 461 462 string packageName = ""; 463 int uid = IPCSkeleton::GetCallingUid(); 464 if (uid <= INVALID_UID) { 465 MEDIA_ERR_LOG("Get INVALID_UID UID %{public}d", uid); 466 return packageName; 467 } 468 GetPackageNameFromCache(uid, bundleName, packageName); 469 470 return packageName; 471} 472 473string PermissionUtils::GetAppIdByBundleName(const string &bundleName) 474{ 475 int uid = IPCSkeleton::GetCallingUid(); 476 return GetAppIdByBundleName(bundleName, uid); 477} 478 479string PermissionUtils::GetAppIdByBundleName(const string &bundleName, int32_t uid) 480{ 481 if (uid <= INVALID_UID) { 482 MEDIA_ERR_LOG("Get INVALID_UID UID %{public}d", uid); 483 return ""; 484 } 485 string appId = ""; 486 GetAppIdFromCache(uid, bundleName, appId); 487 488 return appId; 489} 490 491bool PermissionUtils::SetEPolicy() 492{ 493 MEDIA_INFO_LOG("SetEPolicy for directory"); 494 int ret = Security::AccessToken::El5FilekeyManagerKit::SetFilePathPolicy(); 495 if (ret != 0) { 496 MEDIA_ERR_LOG("SetEPolicy fail of %{public}d", ret); 497 return false; 498 } 499 return true; 500} 501} // namespace Media 502} // namespace OHOS 503