• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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 "init_service.h"
16 
17 #include <dlfcn.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/param.h>
21 #include <sys/resource.h>
22 #include <unistd.h>
23 
24 #include "init_group_manager.h"
25 #include "init.h"
26 #include "init_log.h"
27 #include "init_param.h"
28 #include "init_utils.h"
29 #include "securec.h"
30 #include "token_setproc.h"
31 #include "nativetoken_kit.h"
32 #include "sandbox.h"
33 #include "sandbox_namespace.h"
34 #include "service_control.h"
35 
36 #define MIN_IMPORTANT_LEVEL (-20)
37 #define MAX_IMPORTANT_LEVEL 19
38 
39 static bool g_enableSandbox = false;
40 
NotifyServiceChange(Service * service,int status)41 void NotifyServiceChange(Service *service, int status)
42 {
43     INIT_LOGV("Notify service %s change from %d to %d", service->name, service->status, status);
44     service->status = status;
45     INIT_CHECK(status != SERVICE_IDLE, return);
46     char paramName[PARAM_NAME_LEN_MAX] = { 0 };
47     int ret = snprintf_s(paramName, sizeof(paramName), sizeof(paramName) - 1,
48         "%s.%s", STARTUP_SERVICE_CTL, service->name);
49     char statusStr[MAX_INT_LEN] = {0};
50     int ret1 = snprintf_s(statusStr, sizeof(statusStr), sizeof(statusStr) - 1, "%d", status);
51     if (ret >= 0 && ret1 > 0) {
52         SystemWriteParam(paramName, statusStr);
53     }
54 }
55 
IsForbidden(const char * fieldStr)56 int IsForbidden(const char *fieldStr)
57 {
58     UNUSED(fieldStr);
59     return 0;
60 }
61 
SetImportantValue(Service * service,const char * attrName,int value,int flag)62 int SetImportantValue(Service *service, const char *attrName, int value, int flag)
63 {
64     UNUSED(attrName);
65     UNUSED(flag);
66     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Set service attr failed! null ptr.");
67     if (value >= MIN_IMPORTANT_LEVEL && value <= MAX_IMPORTANT_LEVEL) { // -20~19
68         service->attribute |= SERVICE_ATTR_IMPORTANT;
69         service->importance = value;
70     } else {
71         INIT_LOGE("Importance level = %d, is not between -20 and 19, error", value);
72         return SERVICE_FAILURE;
73     }
74     return SERVICE_SUCCESS;
75 }
76 
ServiceExec(const Service * service)77 int ServiceExec(const Service *service)
78 {
79     INIT_ERROR_CHECK(service != NULL && service->pathArgs.count > 0,
80         return SERVICE_FAILURE, "Exec service failed! null ptr.");
81     if (service->importance != 0) {
82         INIT_ERROR_CHECK(setpriority(PRIO_PROCESS, 0, service->importance) == 0, _exit(0x7f),
83             "setpriority failed for %s, importance = %d, err=%d", service->name, service->importance, errno);
84     }
85     OpenHidebug(service->name);
86     // L2 Can not be reset env
87     if (service->extraArgs.argv != NULL && service->extraArgs.count > 0) {
88         INIT_CHECK_ONLY_ELOG(execv(service->extraArgs.argv[0], service->extraArgs.argv) == 0,
89             "service %s execve failed! err %d.", service->name, errno);
90     } else {
91         INIT_CHECK_ONLY_ELOG(execv(service->pathArgs.argv[0], service->pathArgs.argv) == 0,
92             "service %s execve failed! err %d.", service->name, errno);
93     }
94     return SERVICE_SUCCESS;
95 }
96 
SetAccessToken(const Service * service)97 int SetAccessToken(const Service *service)
98 {
99     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "service is null");
100     int ret = SetSelfTokenID(service->tokenId);
101     if (ret != 0) {
102         INIT_LOGV("Set service %s token id %lld failed.", service->name, service->tokenId);
103         return SERVICE_FAILURE;
104     }
105     return SERVICE_SUCCESS;
106 }
107 
GetAccessToken(void)108 void GetAccessToken(void)
109 {
110     InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
111     while (node != NULL) {
112         Service *service = node->data.service;
113         if (service != NULL) {
114             if (service->capsArgs.count == 0) {
115                 service->capsArgs.argv = NULL;
116             }
117             const char *apl = "system_basic";
118             if (service->apl != NULL) {
119                 apl = service->apl;
120             }
121             NativeTokenInfoParams nativeTokenInfoParams = {
122                 service->capsArgs.count,
123                 service->permArgs.count,
124                 service->permAclsArgs.count,
125                 (const char **)service->capsArgs.argv,
126                 (const char **)service->permArgs.argv,
127                 (const char **)service->permAclsArgs.argv,
128                 service->name,
129                 apl,
130             };
131             uint64_t tokenId = GetAccessTokenId(&nativeTokenInfoParams);
132             INIT_CHECK_ONLY_ELOG(tokenId  != 0,
133                 "Get totken id %lld of service \' %s \' failed", tokenId, service->name);
134             service->tokenId = tokenId;
135         }
136         node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
137     }
138 }
139 
IsEnableSandbox(void)140 void IsEnableSandbox(void)
141 {
142     char value[MAX_BUFFER_LEN] = {0};
143     unsigned int len = MAX_BUFFER_LEN;
144     if (SystemReadParam("const.sandbox", value, &len) == 0) {
145         if (strcmp(value, "enable") == 0) {
146             g_enableSandbox = true;
147         }
148     }
149 }
150 
SetServiceEnterSandbox(const char * execPath,unsigned int attribute)151 void SetServiceEnterSandbox(const char *execPath, unsigned int attribute)
152 {
153     if (g_enableSandbox == false) {
154         return;
155     }
156     if ((attribute & SERVICE_ATTR_WITHOUT_SANDBOX) == SERVICE_ATTR_WITHOUT_SANDBOX) {
157         return;
158     }
159     INIT_ERROR_CHECK(execPath != NULL, return, "Service path is null.");
160     if (strncmp(execPath, "/system/bin/", strlen("/system/bin/")) == 0) {
161         INIT_INFO_CHECK(EnterSandbox("system") == 0, return,
162             "Service %s skip enter system sandbox.", execPath);
163     } else if (strncmp(execPath, "/vendor/bin/", strlen("/vendor/bin/")) == 0) {
164         INIT_INFO_CHECK(EnterSandbox("chipset") == 0, return,
165             "Service %s skip enter chipset sandbox.", execPath);
166     } else {
167         INIT_LOGI("Service %s does not enter sandbox", execPath);
168     }
169     return;
170 }
171