• 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 "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