• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     BundleInfo bundleInfo;
69     if (memset_s(&bundleInfo, sizeof(BundleInfo), 0x00, sizeof(BundleInfo)) != EOK) {
70         HILOGE("[bundleInfo memset failed]");
71         return DMS_EC_FAILURE;
72     }
73     int32_t errCode;
74 #ifndef WEARABLE_PRODUCT
75     uid_t callerUid = getuid();
76     if (callerUid == FOUNDATION_UID) {
77         /* inner-process mode */
78         struct BmsServerProxy *bmsInterface = NULL;
79         if (!GetBmsInterface(&bmsInterface)) {
80             HILOGE("[GetBmsInterface query null]");
81             return DMS_EC_GET_BMS_FAILURE;
82         }
83         if (permissionCheckInfo->calleeBundleName == NULL) {
84             return DMS_EC_FAILURE;
85         }
86         errCode = bmsInterface->GetBundleInfo(permissionCheckInfo->calleeBundleName,
87             GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
88     } else if (callerUid == SHELL_UID) {
89         /* inter-process mode (mainly called in xts testsuit process started by shell) */
90         errCode = GetBundleInfo(permissionCheckInfo->calleeBundleName,
91             GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
92     } else {
93         errCode = EC_FAILURE;
94     }
95 #else
96     errCode = GetBundleInfo(permissionCheckInfo->calleeBundleName,
97         GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
98 #endif
99     if (errCode != EC_SUCCESS) {
100         HILOGE("[GetBundleInfo errCode = %d]", errCode);
101         return DMS_EC_GET_BUNDLEINFO_FAILURE;
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     if (strcmp(permissionCheckInfo->callerSignature, calleeSignature) != 0) {
112         HILOGE("[Signature unmatched]");
113         return DMS_EC_CHECK_PERMISSION_FAILURE;
114     }
115     return DMS_EC_SUCCESS;
116 }
117 
GetBundleInfoFromFile(const char * filePath,BundleInfo * bundleInfo)118 static int32_t GetBundleInfoFromFile(const char *filePath, BundleInfo *bundleInfo)
119 {
120     int32_t fd = open(filePath, O_RDONLY, S_IRUSR);
121     if (fd < 0) {
122         HILOGE("[open file failed]");
123         return DMS_EC_FAILURE;
124     }
125     int32_t fileLen = lseek(fd, 0, SEEK_END);
126     if (fileLen <= 0) {
127         HILOGE("[fileLen is invalid, fileLen=%d]", fileLen);
128         close(fd);
129         return DMS_EC_FAILURE;
130     }
131     int32_t ret = lseek(fd, 0, SEEK_SET);
132     if (ret < 0) {
133         HILOGE("[lseek failed, ret=%d]", ret);
134         close(fd);
135         return DMS_EC_FAILURE;
136     }
137     int32_t appIdLen = fileLen + 1;
138     char *appId = (char *)DMS_ALLOC(appIdLen);
139     if (appId == NULL) {
140         HILOGE("[DMS_ALLOC appId failed]");
141         close(fd);
142         return DMS_EC_FAILURE;
143     }
144     (void)memset_s(appId, appIdLen, 0x00, appIdLen);
145     ret = read(fd, appId, fileLen);
146     if (ret < 0) {
147         HILOGE("[read appId failed, ret=%d]", ret);
148         DMS_FREE(appId);
149         close(fd);
150         return DMS_EC_FAILURE;
151     }
152     for (; fileLen > 0; --fileLen) {
153         if (appId[fileLen - 1] != '\n') {
154             break;
155         }
156     }
157     appId[fileLen] = '\0';
158     bundleInfo->appId = appId;
159     close(fd);
160     return DMS_EC_SUCCESS;
161 }
162 
GetBundleInfoFromBms(const CallerInfo * callerInfo,BundleInfo * bundleInfo)163 static int32_t GetBundleInfoFromBms(const CallerInfo *callerInfo, BundleInfo *bundleInfo)
164 {
165     int32_t errCode;
166 #ifndef WEARABLE_PRODUCT
167     char *bundleName = NULL;
168     uid_t callerUid = getuid();
169     if (callerUid == FOUNDATION_UID) {
170         /* inner-process mode */
171         struct BmsServerProxy *bmsServerProxy = NULL;
172         if (!GetBmsInterface(&bmsServerProxy)) {
173             HILOGE("[GetBmsInterface query null]");
174             return DMS_EC_GET_BMS_FAILURE;
175         }
176         if (bmsServerProxy->GetBundleNameForUid(callerInfo->uid, &bundleName) != EC_SUCCESS) {
177             HILOGE("[GetBundleNameForUid failed]");
178             return DMS_EC_FAILURE;
179         }
180         errCode = bmsServerProxy->GetBundleInfo(bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
181     } else if (callerUid == SHELL_UID) {
182         /* inter-process mode (mainly called in xts testsuit process started by shell) */
183         if (GetBundleNameForUid(callerInfo->uid, &bundleName) != EC_SUCCESS) {
184             HILOGE("[GetBundleNameForUid failed]");
185             return DMS_EC_FAILURE;
186         }
187         errCode = GetBundleInfo(bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
188     } else {
189         errCode = DMS_EC_FAILURE;
190     }
191     DMS_FREE(bundleName);
192 #else
193     errCode = GetBundleInfo(callerInfo->bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
194 #endif
195     if (errCode != EC_SUCCESS) {
196         HILOGE("[GetBundleInfo failed]");
197         return DMS_EC_GET_BUNDLEINFO_FAILURE;
198     }
199     return DMS_EC_SUCCESS;
200 }
201 
GetCallerBundleInfo(const CallerInfo * callerInfo,BundleInfo * bundleInfo)202 int32_t GetCallerBundleInfo(const CallerInfo *callerInfo, BundleInfo *bundleInfo)
203 {
204     if ((callerInfo == NULL) || (bundleInfo == NULL)) {
205         HILOGE("[invalid parameter]");
206         return DMS_EC_INVALID_PARAMETER;
207     }
208 #ifndef WEARABLE_PRODUCT
209     if (callerInfo->uid <= MAX_NATIVE_SERVICE_UID) {
210         char filePath[MAX_FILE_PATH_LEN] = {0};
211         int32_t ret = sprintf_s(filePath, MAX_FILE_PATH_LEN, "%s%s%d%s", NATIVE_APPID_DIR, APPID_FILE_PREFIX,
212             callerInfo->uid, APPID_FILE_SUFFIX);
213         if (ret < 0) {
214             HILOGE("[filePath sprintf failed]");
215             return DMS_EC_FAILURE;
216         }
217         bundleInfo->uid = callerInfo->uid;
218         return GetBundleInfoFromFile(filePath, bundleInfo);
219     }
220 #endif
221     return GetBundleInfoFromBms(callerInfo, bundleInfo);
222 }
223