1 /*
2 * Copyright (c) 2020 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 "dmslite_permission.h"
17
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #ifdef WEARABLE_PRODUCT
24 #include "bundle_manager.h"
25 #else
26 #include "bundle_inner_interface.h"
27 #include "bundle_manager.h"
28 #endif
29 #include "dmslite_log.h"
30 #include "dmslite_utils.h"
31 #include "samgr_lite.h"
32 #include "securec.h"
33
34 #define DELIMITER_LENGTH 1
35 #define GET_BUNDLE_WITHOUT_ABILITIES 0
36 #ifndef WEARABLE_PRODUCT
37 #define NATIVE_APPID_DIR "/system/native_appid/"
38 #define APPID_FILE_PREFIX "uid_"
39 #define APPID_FILE_SUFFIX "_appid"
40 #define MAX_FILE_PATH_LEN 64
41 #define MAX_NATIVE_SERVICE_UID 99
42 #endif
43
44 #ifndef WEARABLE_PRODUCT
GetBmsInterface(struct BmsServerProxy ** bmsInterface)45 static bool GetBmsInterface(struct BmsServerProxy **bmsInterface)
46 {
47 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BMS_SERVICE, BMS_FEATURE);
48 if (iUnknown == NULL) {
49 HILOGE("[GetFeatureApi failed]");
50 return false;
51 }
52
53 int32_t errCode = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **) bmsInterface);
54 if (errCode != EC_SUCCESS) {
55 HILOGE("[QueryInterface failed]");
56 return false;
57 }
58
59 return true;
60 }
61 #endif
62
CheckRemotePermission(const PermissionCheckInfo * permissionCheckInfo)63 int32_t CheckRemotePermission(const PermissionCheckInfo *permissionCheckInfo)
64 {
65 if (permissionCheckInfo == NULL) {
66 return DMS_EC_FAILURE;
67 }
68
69 BundleInfo bundleInfo;
70 if (memset_s(&bundleInfo, sizeof(BundleInfo), 0x00, sizeof(BundleInfo)) != EOK) {
71 HILOGE("[bundleInfo memset failed]");
72 return DMS_EC_FAILURE;
73 }
74
75 int32_t errCode;
76 #ifndef WEARABLE_PRODUCT
77 uid_t callerUid = getuid();
78 if (callerUid == FOUNDATION_UID) {
79 /* inner-process mode */
80 struct BmsServerProxy *bmsInterface = NULL;
81 if (!GetBmsInterface(&bmsInterface)) {
82 HILOGE("[GetBmsInterface query null]");
83 return DMS_EC_GET_BMS_FAILURE;
84 }
85 errCode = bmsInterface->GetBundleInfo(permissionCheckInfo->calleeBundleName,
86 GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
87 } else if (callerUid == SHELL_UID) {
88 /* inter-process mode (mainly called in xts testsuit process started by shell) */
89 errCode = GetBundleInfo(permissionCheckInfo->calleeBundleName,
90 GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
91 } else {
92 errCode = EC_FAILURE;
93 }
94 #else
95 errCode = GetBundleInfo(permissionCheckInfo->calleeBundleName,
96 GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
97 #endif
98 if (errCode != EC_SUCCESS) {
99 HILOGE("[GetBundleInfo errCode = %d]", errCode);
100 return DMS_EC_GET_BUNDLEINFO_FAILURE;
101 }
102
103 /* appId: bundleName + "_" + signature */
104 const char *calleeSignature = bundleInfo.appId + strlen(permissionCheckInfo->calleeBundleName)
105 + DELIMITER_LENGTH;
106 ClearBundleInfo(&bundleInfo);
107 if ((permissionCheckInfo->callerSignature == NULL) || (calleeSignature == NULL)) {
108 HILOGE("[Signature is null]");
109 return DMS_EC_FAILURE;
110 }
111
112 if (strcmp(permissionCheckInfo->callerSignature, calleeSignature) != 0) {
113 HILOGE("[Signature unmatched]");
114 return DMS_EC_CHECK_PERMISSION_FAILURE;
115 }
116
117 return DMS_EC_SUCCESS;
118 }
119
GetBundleInfoFromFile(const char * filePath,BundleInfo * bundleInfo)120 static int32_t GetBundleInfoFromFile(const char *filePath, BundleInfo *bundleInfo)
121 {
122 int32_t fd = open(filePath, O_RDONLY, S_IRUSR);
123 if (fd < 0) {
124 HILOGE("[open file failed]");
125 return DMS_EC_FAILURE;
126 }
127 int32_t fileLen = lseek(fd, 0, SEEK_END);
128 if (fileLen <= 0) {
129 HILOGE("[fileLen is invalid, fileLen=%d]", fileLen);
130 close(fd);
131 return DMS_EC_FAILURE;
132 }
133 int32_t ret = lseek(fd, 0, SEEK_SET);
134 if (ret < 0) {
135 HILOGE("[lseek failed, ret=%d]", ret);
136 close(fd);
137 return DMS_EC_FAILURE;
138 }
139 int32_t appIdLen = fileLen + 1;
140 char *appId = (char *)DMS_ALLOC(appIdLen);
141 if (appId == NULL) {
142 HILOGE("[DMS_ALLOC appId failed]");
143 close(fd);
144 return DMS_EC_FAILURE;
145 }
146 (void)memset_s(appId, appIdLen, 0x00, appIdLen);
147 ret = read(fd, appId, fileLen);
148 if (ret < 0) {
149 HILOGE("[read appId failed, ret=%d]", ret);
150 DMS_FREE(appId);
151 close(fd);
152 return DMS_EC_FAILURE;
153 }
154 for (; fileLen > 0; --fileLen) {
155 if (appId[fileLen - 1] != '\n') {
156 break;
157 }
158 }
159 appId[fileLen] = '\0';
160 bundleInfo->appId = appId;
161 close(fd);
162 return DMS_EC_SUCCESS;
163 }
164
GetBundleInfoFromBms(const CallerInfo * callerInfo,BundleInfo * bundleInfo)165 static int32_t GetBundleInfoFromBms(const CallerInfo *callerInfo, BundleInfo *bundleInfo)
166 {
167 int32_t errCode;
168 #ifndef WEARABLE_PRODUCT
169 char *bundleName = NULL;
170 uid_t callerUid = getuid();
171 if (callerUid == FOUNDATION_UID) {
172 /* inner-process mode */
173 struct BmsServerProxy *bmsServerProxy = NULL;
174 if (!GetBmsInterface(&bmsServerProxy)) {
175 HILOGE("[GetBmsInterface query null]");
176 return DMS_EC_GET_BMS_FAILURE;
177 }
178 if (bmsServerProxy->GetBundleNameForUid(callerInfo->uid, &bundleName) != EC_SUCCESS) {
179 HILOGE("[GetBundleNameForUid failed]");
180 return DMS_EC_FAILURE;
181 }
182 errCode = bmsServerProxy->GetBundleInfo(bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
183 } else if (callerUid == SHELL_UID) {
184 /* inter-process mode (mainly called in xts testsuit process started by shell) */
185 if (GetBundleNameForUid(callerInfo->uid, &bundleName) != EC_SUCCESS) {
186 HILOGE("[GetBundleNameForUid failed]");
187 return DMS_EC_FAILURE;
188 }
189 errCode = GetBundleInfo(bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
190 } else {
191 errCode = DMS_EC_FAILURE;
192 }
193 DMS_FREE(bundleName);
194 #else
195 errCode = GetBundleInfo(callerInfo->bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
196 #endif
197 if (errCode != EC_SUCCESS) {
198 HILOGE("[GetBundleInfo failed]");
199 return DMS_EC_GET_BUNDLEINFO_FAILURE;
200 }
201 return DMS_EC_SUCCESS;
202 }
203
GetCallerBundleInfo(const CallerInfo * callerInfo,BundleInfo * bundleInfo)204 int32_t GetCallerBundleInfo(const CallerInfo *callerInfo, BundleInfo *bundleInfo)
205 {
206 if ((callerInfo == NULL) || (bundleInfo == NULL)) {
207 HILOGE("[invalid parameter]");
208 return DMS_EC_INVALID_PARAMETER;
209 }
210 #ifndef WEARABLE_PRODUCT
211 if (callerInfo->uid <= MAX_NATIVE_SERVICE_UID) {
212 char filePath[MAX_FILE_PATH_LEN] = {0};
213 int32_t ret = sprintf_s(filePath, MAX_FILE_PATH_LEN, "%s%s%d%s", NATIVE_APPID_DIR, APPID_FILE_PREFIX,
214 callerInfo->uid, APPID_FILE_SUFFIX);
215 if (ret < 0) {
216 HILOGE("[filePath sprintf failed]");
217 return DMS_EC_FAILURE;
218 }
219 bundleInfo->uid = callerInfo->uid;
220 return GetBundleInfoFromFile(filePath, bundleInfo);
221 }
222 #endif
223 return GetBundleInfoFromBms(callerInfo, bundleInfo);
224 }
225