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
33 namespace OHOS {
34 namespace Media {
35 using namespace std;
36 using namespace OHOS::Security::AccessToken;
37 using namespace OHOS::AppExecFwk::Constants;
38
39 const int32_t CAPACITY = 50;
40 const int32_t HDC_SHELL_UID = 2000;
41 const int32_t BASE_USER_RANGE = 200000;
42
43 std::mutex PermissionUtils::uninstallMutex_;
44 std::list<std::pair<int32_t, BundleInfo>> PermissionUtils::bundleInfoList_ = {};
45 std::unordered_map<int32_t, std::list<std::pair<int32_t, BundleInfo>>::iterator> PermissionUtils::bundleInfoMap_ = {};
46
47 bool g_isDelayTask;
48 std::mutex addPhotoPermissionRecordLock_;
49 std::thread delayTask_;
50 std::vector<Security::AccessToken::AddPermParamInfo> infos_;
51
52 sptr<AppExecFwk::IBundleMgr> PermissionUtils::bundleMgr_ = nullptr;
53 mutex PermissionUtils::bundleMgrMutex_;
GetSysBundleManager()54 sptr<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
GetBundleNameFromCache(int uid, string &bundleName)87 void 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
GetPackageNameFromCache(int uid, const string &bundleName, string &packageName)110 void 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
GetAppIdFromCache(int uid, const string &bundleName, string &appId)142 void 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
UpdateLatestBundleInfo(int uid, const BundleInfo &bundleInfo)165 void 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
UpdateBundleNameInCache(int uid, const string &bundleName)180 void 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
UpdatePackageNameInCache(int uid, const string &packageName)193 void 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
UpdateAppIdInCache(int uid, const string &appId)206 void 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
ClearBundleInfoInCache()217 void 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
GetClientBundle(const int uid, string &bundleName)225 void PermissionUtils::GetClientBundle(const int uid, string &bundleName)
226 {
227 GetBundleNameFromCache(uid, bundleName);
228 }
229
GetPackageName(const int uid, std::string &packageName)230 void 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
ShouldAddPermissionRecord(const AccessTokenID &token)243 bool inline ShouldAddPermissionRecord(const AccessTokenID &token)
244 {
245 return (AccessTokenKit::GetTokenTypeFlag(token) == TOKEN_HAP);
246 }
247
AddPermissionRecord(const AccessTokenID &token, const string &perm, const bool permGranted)248 void 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
GetPermissionRecord()262 vector<AddPermParamInfo> GetPermissionRecord()
263 {
264 lock_guard<mutex> lock(addPhotoPermissionRecordLock_);
265 vector<AddPermParamInfo> result = infos_;
266 infos_.clear();
267 return result;
268 }
269
AddPermissionRecord()270 void 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
DelayAddPermissionRecord()287 void 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
DelayTaskInit()298 void 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
CollectPermissionRecord(const AccessTokenID &token, const string &perm, const bool permGranted, const PermissionUsedType type)308 void 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
CollectPermissionInfo(const string &permission, const bool permGranted, const PermissionUsedType type)331 void 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
CheckPhotoCallerPermission(const string &permission)338 bool 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
CheckPhotoCallerPermission(const vector<string> &perms)352 bool 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
CheckCallerPermission(const string &permission)366 bool 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 */
CheckHasPermission(const vector<string> &perms)384 bool 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 */
CheckCallerPermission(const vector<string> &perms)400 bool 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
GetTokenId()414 uint32_t PermissionUtils::GetTokenId()
415 {
416 return IPCSkeleton::GetCallingTokenID();
417 }
418
IsSystemApp()419 bool PermissionUtils::IsSystemApp()
420 {
421 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
422 return TokenIdKit::IsSystemAppByFullTokenID(tokenId);
423 }
424
CheckIsSystemAppByUid()425 bool 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
IsNativeSAApp()436 bool 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
IsRootShell()448 bool PermissionUtils::IsRootShell()
449 {
450 return IPCSkeleton::GetCallingUid() == 0;
451 }
452
IsHdcShell()453 bool PermissionUtils::IsHdcShell()
454 {
455 return IPCSkeleton::GetCallingUid() == HDC_SHELL_UID;
456 }
457
GetPackageNameByBundleName(const string &bundleName)458 string 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
GetAppIdByBundleName(const string &bundleName)473 string PermissionUtils::GetAppIdByBundleName(const string &bundleName)
474 {
475 int uid = IPCSkeleton::GetCallingUid();
476 return GetAppIdByBundleName(bundleName, uid);
477 }
478
GetAppIdByBundleName(const string &bundleName, int32_t uid)479 string 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
SetEPolicy()491 bool 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