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 "service_control.h"
33
34 #define MIN_IMPORTANT_LEVEL (-20)
35 #define MAX_IMPORTANT_LEVEL 19
36
NotifyServiceChange(Service * service,int status)37 void NotifyServiceChange(Service *service, int status)
38 {
39 int size = 0;
40 const InitArgInfo *statusMap = GetServieStatusMap(&size);
41 INIT_ERROR_CHECK(statusMap != NULL && size > status, service->status = status;
42 return, "Service status error %d", status);
43 INIT_LOGI("NotifyServiceChange %s %s to %s", service->name,
44 statusMap[service->status].name, statusMap[status].name);
45 service->status = status;
46 if (status == SERVICE_IDLE) {
47 return;
48 }
49 char paramName[PARAM_NAME_LEN_MAX] = { 0 };
50 int ret = snprintf_s(paramName, sizeof(paramName), sizeof(paramName) - 1,
51 "%s.%s", STARTUP_SERVICE_CTL, service->name);
52 if (ret >= 0) {
53 SystemWriteParam(paramName, statusMap[status].name);
54 }
55 }
56
IsForbidden(const char * fieldStr)57 int IsForbidden(const char *fieldStr)
58 {
59 UNUSED(fieldStr);
60 return 0;
61 }
62
SetImportantValue(Service * service,const char * attrName,int value,int flag)63 int SetImportantValue(Service *service, const char *attrName, int value, int flag)
64 {
65 UNUSED(attrName);
66 UNUSED(flag);
67 INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Set service attr failed! null ptr.");
68 if (value >= MIN_IMPORTANT_LEVEL && value <= MAX_IMPORTANT_LEVEL) { // -20~19
69 service->attribute |= SERVICE_ATTR_IMPORTANT;
70 service->importance = value;
71 } else {
72 INIT_LOGE("Importance level = %d, is not between -20 and 19, error", value);
73 return SERVICE_FAILURE;
74 }
75 return SERVICE_SUCCESS;
76 }
77
ServiceExec(const Service * service)78 int ServiceExec(const Service *service)
79 {
80 INIT_ERROR_CHECK(service != NULL && service->pathArgs.count > 0,
81 return SERVICE_FAILURE, "Exec service failed! null ptr.");
82 if (service->importance != 0) {
83 if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
84 INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
85 service->name, service->importance, errno);
86 _exit(0x7f); // 0x7f: user specified
87 }
88 }
89 INIT_CHECK_ONLY_ELOG(unsetenv("UV_THREADPOOL_SIZE") == 0, "set UV_THREADPOOL_SIZE error : %d.", errno);
90 #ifdef SUPPORT_PROFILER_HIDEBUG
91 do {
92 if (access("/system/lib/libhidebug.so", F_OK) != 0) {
93 INIT_LOGE("access failed, errno = %d\n", errno);
94 break;
95 }
96 void* handle = dlopen("/system/lib/libhidebug.so", RTLD_LAZY);
97 if (handle == NULL) {
98 INIT_LOGE("Failed to dlopen libhidebug.so, %s\n", dlerror());
99 break;
100 }
101 bool (* initParam)();
102 initParam = (bool (*)())dlsym(handle, "InitEnvironmentParam");
103 if (initParam == NULL) {
104 INIT_LOGE("Failed to dlsym InitEnvironmentParam, %s\n", dlerror());
105 dlclose(handle);
106 break;
107 }
108 bool ret = (*initParam)(service->name);
109 if (!ret) {
110 INIT_LOGE("init parameters failed.\n");
111 }
112 dlclose(handle);
113 } while (0);
114 #endif
115 // L2 Can not be reset env
116 if (service->extraArgs.argv != NULL && service->extraArgs.count > 0) {
117 INIT_CHECK_ONLY_ELOG(execv(service->extraArgs.argv[0], service->extraArgs.argv) == 0,
118 "service %s execve failed! err %d.", service->name, errno);
119 } else {
120 INIT_CHECK_ONLY_ELOG(execv(service->pathArgs.argv[0], service->pathArgs.argv) == 0,
121 "service %s execve failed! err %d.", service->name, errno);
122 }
123 return SERVICE_SUCCESS;
124 }
125
SetAccessToken(const Service * service)126 int SetAccessToken(const Service *service)
127 {
128 INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "service is null");
129 int ret = SetSelfTokenID(service->tokenId);
130 INIT_LOGI("%s: token id %lld, set token id result %d", service->name, service->tokenId, ret);
131 return ret == 0 ? SERVICE_SUCCESS : SERVICE_FAILURE;
132 }
133
GetAccessToken(void)134 void GetAccessToken(void)
135 {
136 InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
137 while (node != NULL) {
138 Service *service = node->data.service;
139 if (service != NULL) {
140 if (service->capsArgs.count == 0) {
141 service->capsArgs.argv = NULL;
142 }
143 if (strlen(service->apl) == 0) {
144 (void)strncpy_s(service->apl, sizeof(service->apl), "system_core", sizeof(service->apl) - 1);
145 }
146 uint64_t tokenId = GetAccessTokenId(service->name, (const char **)service->capsArgs.argv,
147 service->capsArgs.count, service->apl);
148 if (tokenId == 0) {
149 INIT_LOGE("Get totken id %lld of service \' %s \' failed", tokenId, service->name);
150 }
151 service->tokenId = tokenId;
152 }
153 node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
154 }
155 }
156