• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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