1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License"){return 0;}
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 #define MLOG_TAG "MediaPermissionCheck"
16 #include <string>
17
18 #include "dfx_deprecated_perm_usage.h"
19 #include "media_write_permission_check.h"
20 #include "media_file_utils.h"
21 #include "ipc_skeleton.h"
22 #ifdef MEDIALIBRARY_SECURITY_OPEN
23 #include "sec_comp_kit.h"
24 #endif
25 #include "parameters.h"
26 #include "access_token.h"
27 #include "media_app_uri_permission_column.h"
28
29 namespace OHOS::Media {
30 using namespace OHOS::Security::AccessToken;
31 static const int32_t GRANT_PERMISSION_CALLING_UID = 5523; // foundation调用方
32 static const int32_t ROOT_UID = 0;
33 static const int32_t HDC_SHELL_UID = 2000;
34 static const int32_t SANDBOX_UID = 3076;
35 static int32_t AcrossLocalAccountsPermCheck(const PermissionHeaderReq &data);
WriteCompositePermCheck()36 WriteCompositePermCheck::WriteCompositePermCheck()
37 {
38 auto writePrivilegePermCheck = std::make_shared<WritePrivilegePermCheck>();
39 AddCheck(writePrivilegePermCheck);
40
41 auto dbWritePermCheck = std::make_shared<DbWritePermCheck>();
42 AddCheck(dbWritePermCheck);
43
44 auto grantWritePermCheck = std::make_shared<GrantWritePermCheck>();
45 AddCheck(grantWritePermCheck);
46
47 auto mediaToolWritePermCheck = std::make_shared<MediaToolWritePermCheck>();
48 AddCheck(mediaToolWritePermCheck);
49
50 auto securityComponentPermCheck = std::make_shared<SecurityComponentPermCheck>();
51 AddCheck(securityComponentPermCheck);
52
53 auto shortTermWritePermCheck = std::make_shared<ShortTermWritePermCheck>();
54 AddCheck(shortTermWritePermCheck);
55
56 auto deprecatedWritePermCheck = std::make_shared<DeprecatedWritePermCheck>();
57 AddCheck(deprecatedWritePermCheck);
58 }
59
AddCheck(std::shared_ptr<PermissionCheck> check)60 void WriteCompositePermCheck::AddCheck(std::shared_ptr<PermissionCheck> check)
61 {
62 std::lock_guard<std::mutex> lock(mutex_);
63 writeChecks_.push_back(check);
64 }
65
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)66 int32_t WriteCompositePermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
67 {
68 MEDIA_INFO_LOG("WriteCompositePermCheck enter, API code=%{public}d", businessCode);
69 int32_t err = AcrossLocalAccountsPermCheck(data);
70 if (err != E_SUCCESS) {
71 return E_PERMISSION_DENIED;
72 }
73 if (isCalledBySelfPtr() == E_OK) {
74 MEDIA_INFO_LOG("WriteCompositePermCheck isCalledBySelfPtr check success");
75 return E_SUCCESS;
76 }
77 MEDIA_INFO_LOG("WriteCompositePermCheck isCalledBySelfPtr check fail");
78
79 for (const auto& check : writeChecks_) {
80 if (check->CheckPermission(businessCode, data) == E_SUCCESS) {
81 return E_SUCCESS;
82 }
83 }
84
85 return E_PERMISSION_DENIED;
86 }
87
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)88 int32_t WritePrivilegePermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
89 {
90 MEDIA_INFO_LOG("WritePrivilegePermCheck enter, API code=%{public}d", businessCode);
91 return PermissionUtils::CheckCallerPermission(PERM_WRITE_IMAGEVIDEO) ? E_SUCCESS : E_PERMISSION_DENIED;
92 }
93
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)94 int32_t DbWritePermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
95 {
96 MEDIA_INFO_LOG("DbWritePermCheck enter, API code=%{public}d", businessCode);
97 int32_t permissionType = 0;
98 auto ret = DbPermissionCheck::GetPermissionType(businessCode, data, permissionType);
99 if (ret != E_SUCCESS) {
100 return ret;
101 }
102 return (AppUriPermissionColumn::PERMISSION_TYPE_WRITE.count(permissionType)) ? E_SUCCESS : E_PERMISSION_DENIED;
103 }
104
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)105 int32_t GrantWritePermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
106 {
107 MEDIA_INFO_LOG("GrantWritePermCheck enter, API code=%{public}d", businessCode);
108 if (PermissionCheck::grantOperationPermissionSet.find(businessCode) ==
109 PermissionCheck::grantOperationPermissionSet.end()) {
110 MEDIA_INFO_LOG("Not grant operation");
111 return E_PERMISSION_DENIED;
112 }
113 if (getCallingUidPtr() == GRANT_PERMISSION_CALLING_UID ||
114 getCallingUidPtr() == ROOT_UID || getCallingUidPtr() == SANDBOX_UID) {
115 MEDIA_INFO_LOG("GrantWritePermCheck callingUid check success");
116 return E_SUCCESS;
117 }
118 MEDIA_INFO_LOG("GrantWritePermCheck callingUid check fail");
119 return E_PERMISSION_DENIED;
120 }
121
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)122 int32_t MediaToolWritePermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
123 {
124 MEDIA_INFO_LOG("MediaToolWritePermCheck enter, API code=%{public}d", businessCode);
125 if (PermissionCheck::mediaToolOperationPermissionSet.find(businessCode) ==
126 PermissionCheck::mediaToolOperationPermissionSet.end()) {
127 MEDIA_INFO_LOG("Not media tool operation");
128 return E_PERMISSION_DENIED;
129 }
130 if (getCallingUidPtr() != ROOT_UID && getCallingUidPtr() != HDC_SHELL_UID) {
131 MEDIA_ERR_LOG("Mediatool permission check failed: target is not root");
132 return E_PERMISSION_DENIED;
133 }
134 if (!OHOS::system::GetBoolParameter("const.security.developermode.state", true)) {
135 MEDIA_ERR_LOG("Mediatool permission check failed: target is not in developer mode");
136 return E_PERMISSION_DENIED;
137 }
138 return E_SUCCESS;
139 }
140
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)141 int32_t SecurityComponentPermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
142 {
143 MEDIA_INFO_LOG("SecurityComponentPermCheck enter, API code=%{public}d", businessCode);
144 #ifdef MEDIALIBRARY_SECURITY_OPEN
145 auto tokenId = PermissionUtils::GetTokenId();
146 if (!Security::SecurityComponent::SecCompKit::VerifySavePermission(tokenId)) {
147 MEDIA_ERR_LOG("Failed to verify save permission of security component");
148 return E_PERMISSION_DENIED;
149 }
150 return E_SUCCESS;
151 #else
152 MEDIA_ERR_LOG("Security component is not existed");
153 return E_PERMISSION_DENIED;
154 #endif
155 };
156
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)157 int32_t ShortTermWritePermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
158 {
159 MEDIA_INFO_LOG("ShortTermWritePermCheck enter, API code=%{public}d", businessCode);
160 if (PermissionUtils::CheckPhotoCallerPermission(PERM_SHORT_TERM_WRITE_IMAGEVIDEO)) {
161 AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID();
162 int err = Security::AccessToken::AccessTokenKit::GrantPermissionForSpecifiedTime(tokenCaller,
163 PERM_SHORT_TERM_WRITE_IMAGEVIDEO, SHORT_TERM_PERMISSION_DURATION_300S);
164 CHECK_AND_RETURN_RET_LOG(err >= 0, err, "GrantPermissionForSpecifiedTime errCode: %{public}d", err);
165 return E_SUCCESS;
166 }
167 return E_PERMISSION_DENIED;
168 }
169
CheckPermission(uint32_t businessCode,const PermissionHeaderReq & data)170 int32_t DeprecatedWritePermCheck::CheckPermission(uint32_t businessCode, const PermissionHeaderReq &data)
171 {
172 MEDIA_INFO_LOG("DeprecatedWritePermCheck enter, API code=%{public}d", businessCode);
173 if (PermissionCheck::deprecatedWritePermissionSet.find(businessCode) ==
174 PermissionCheck::deprecatedWritePermissionSet.end()) {
175 MEDIA_INFO_LOG("Unable to use deprecated write permission");
176 return E_PERMISSION_DENIED;
177 }
178 bool ret = PermissionUtils::CheckCallerPermission(PERMISSION_NAME_WRITE_MEDIA);
179 CHECK_AND_EXECUTE(!ret, DfxDeprecatedPermUsage::Record(businessCode, 0));
180 return ret ? E_SUCCESS : E_PERMISSION_DENIED;
181 }
182
AcrossLocalAccountsPermCheck(const PermissionHeaderReq & data)183 static int32_t AcrossLocalAccountsPermCheck(const PermissionHeaderReq &data)
184 {
185 int32_t userId = data.getUserId();
186 if (userId == -1) {
187 return E_SUCCESS;
188 }
189 std::vector<std::string> perms;
190 perms.push_back(PERM_INTERACT_ACROSS_LOCAL_ACCOUNTS);
191 return PermissionUtils::CheckCallerPermission(perms) ? E_SUCCESS : E_PERMISSION_DENIED;
192 }
193
194 } // namespace OHOS::Media
195