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