1 /*
2 * Copyright (c) 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
16 #include <dlfcn.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #ifdef __MUSL__
23 #include <stropts.h>
24 #endif
25 #include <sys/prctl.h>
26 #include <sys/capability.h>
27 #include <sys/ioctl.h>
28 #include <sys/param.h>
29 #include <sys/resource.h>
30 #include <sys/stat.h>
31 #include <time.h>
32 #include <unistd.h>
33
34 #include "init.h"
35 #include "init_adapter.h"
36 #include "init_cmds.h"
37 #include "init_cmdexecutor.h"
38 #include "init_log.h"
39 #include "init_cmdexecutor.h"
40 #include "init_jobs_internal.h"
41 #include "init_param.h"
42 #include "init_service.h"
43 #include "init_service_manager.h"
44 #include "init_service_socket.h"
45 #include "init_utils.h"
46 #include "fd_holder_internal.h"
47 #include "loop_event.h"
48 #include "securec.h"
49 #include "service_control.h"
50 #include "init_group_manager.h"
51 #ifndef OHOS_LITE
52 #include "init_hisysevent.h"
53 #endif
54
55 #if defined(ENABLE_HOOK_MGR)
56 #include "hookmgr.h"
57 #include "bootstage.h"
58 #endif
59
60 #ifdef WITH_SECCOMP
61 #define APPSPAWN_NAME ("appspawn")
62 #define NWEBSPAWN_NAME ("nwebspawn")
63 #endif
64
65 #ifndef TIOCSCTTY
66 #define TIOCSCTTY 0x540E
67 #endif
68
69 #define DEF_CRASH_TIME 240000 // default crash time is 240000 ms
70
SetAllAmbientCapability(void)71 static int SetAllAmbientCapability(void)
72 {
73 for (int i = 0; i <= CAP_LAST_CAP; ++i) {
74 if (SetAmbientCapability(i) != 0) {
75 return SERVICE_FAILURE;
76 }
77 }
78 return SERVICE_SUCCESS;
79 }
80
SetSystemSeccompPolicy(const Service * service)81 static int SetSystemSeccompPolicy(const Service *service)
82 {
83 #ifdef WITH_SECCOMP
84 if (strncmp(APPSPAWN_NAME, service->name, strlen(APPSPAWN_NAME))
85 && strncmp(NWEBSPAWN_NAME, service->name, strlen(NWEBSPAWN_NAME))) {
86 char cmdContent[MAX_CMD_CONTENT_LEN + 1] = {0};
87
88 int rc = snprintf_s(cmdContent, MAX_CMD_CONTENT_LEN + 1, strlen(service->name) + 1,
89 "%s ", service->name);
90 if (rc == -1) {
91 return SERVICE_FAILURE;
92 }
93
94 rc = strcat_s(cmdContent, MAX_CMD_CONTENT_LEN + 1, service->pathArgs.argv[0]);
95 if (rc != 0) {
96 return SERVICE_FAILURE;
97 }
98
99 PluginExecCmdByName("SetSeccompPolicy", cmdContent);
100 }
101 #endif
102 return SERVICE_SUCCESS;
103 }
104
105 #if defined(ENABLE_HOOK_MGR)
106 /**
107 * service Hooking
108 */
ServiceHookWrapper(const HOOK_INFO * hookInfo,void * executionContext)109 static int ServiceHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
110 {
111 SERVICE_INFO_CTX *serviceContext = (SERVICE_INFO_CTX *)executionContext;
112 ServiceHook realHook = (ServiceHook)hookInfo->hookCookie;
113
114 realHook(serviceContext);
115 return 0;
116 };
117
InitAddServiceHook(ServiceHook hook,int hookState)118 int InitAddServiceHook(ServiceHook hook, int hookState)
119 {
120 HOOK_INFO info;
121
122 info.stage = hookState;
123 info.prio = 0;
124 info.hook = ServiceHookWrapper;
125 info.hookCookie = (void *)hook;
126
127 return HookMgrAddEx(GetBootStageHookMgr(), &info);
128 }
129
ServiceRestartHookWrapper(const HOOK_INFO * hookInfo,void * executionContext)130 static int ServiceRestartHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
131 {
132 SERVICE_RESTART_CTX *serviceContext = (SERVICE_RESTART_CTX *)executionContext;
133 ServiceRestartHook realHook = (ServiceRestartHook)hookInfo->hookCookie;
134
135 realHook(serviceContext);
136 return 0;
137 }
138
InitServiceRestartHook(ServiceRestartHook hook,int hookState)139 int InitServiceRestartHook(ServiceRestartHook hook, int hookState)
140 {
141 HOOK_INFO info;
142
143 info.stage = hookState;
144 info.prio = 0;
145 info.hook = ServiceRestartHookWrapper;
146 info.hookCookie = (void *)hook;
147
148 return HookMgrAddEx(GetBootStageHookMgr(), &info);
149 }
150
151 /**
152 * service hooking execute
153 */
ServiceHookExecute(const char * serviceName,const char * info,int stage)154 static void ServiceHookExecute(const char *serviceName, const char *info, int stage)
155 {
156 SERVICE_INFO_CTX context;
157
158 context.serviceName = serviceName;
159 context.reserved = info;
160
161 (void)HookMgrExecute(GetBootStageHookMgr(), stage, (void *)(&context), NULL);
162 }
163 #endif
164
ServiceSetGid(const Service * service)165 static int ServiceSetGid(const Service *service)
166 {
167 if (service->servPerm.gIDCnt == 0) {
168 // use uid as gid
169 INIT_ERROR_CHECK(setgid(service->servPerm.uID) == 0, return SERVICE_FAILURE,
170 "Service error %d %s, failed to set gid.", errno, service->name);
171 }
172 if (service->servPerm.gIDCnt > 0) {
173 INIT_ERROR_CHECK(setgid(service->servPerm.gIDArray[0]) == 0, return SERVICE_FAILURE,
174 "Service error %d %s, failed to set gid.", errno, service->name);
175 }
176 if (service->servPerm.gIDCnt > 1) {
177 INIT_ERROR_CHECK(setgroups(service->servPerm.gIDCnt - 1, (const gid_t *)&service->servPerm.gIDArray[1]) == 0,
178 return SERVICE_FAILURE,
179 "Service error %d %s, failed to set gid.", errno, service->name);
180 }
181
182 return SERVICE_SUCCESS;
183 }
184
GetInvalidCaps(const Service * service,unsigned int * caps)185 static void GetInvalidCaps(const Service *service, unsigned int *caps)
186 {
187 int index = 0;
188 bool flags = false;
189 for (unsigned int cap = 0; cap <= CAP_LAST_CAP; cap++) {
190 for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
191 if (cap == service->servPerm.caps[i]) {
192 flags = true;
193 break;
194 }
195 flags = false;
196 }
197 if (!flags) {
198 caps[index] = cap;
199 index++;
200 }
201 }
202 }
203
DropCapability(const Service * service)204 static void DropCapability(const Service *service)
205 {
206 #if defined(ENABLE_HOOK_MGR)
207 int invalidCnt = CAP_LAST_CAP - service->servPerm.capsCnt + 1;
208 unsigned int *caps = (unsigned int *)calloc(invalidCnt, sizeof(unsigned int));
209 INIT_ERROR_CHECK(caps != NULL, return, "calloc caps failed! error:%d", errno);
210
211 GetInvalidCaps(service, caps);
212 for (int i = 0; i < invalidCnt; i++) {
213 if (prctl(PR_CAPBSET_DROP, caps[i])) {
214 INIT_LOGE("prctl PR_SET_SECUREBITS failed: %d", errno);
215 free(caps);
216 return;
217 }
218 }
219 free(caps);
220 #else
221 return;
222 #endif
223 }
224
SetPerms(const Service * service)225 static int SetPerms(const Service *service)
226 {
227 #if defined(ENABLE_HOOK_MGR)
228 /*
229 * service before setting Perms hooks
230 */
231 ServiceHookExecute(service->name, (const char *)service->pathArgs.argv[0], INIT_SERVICE_SET_PERMS_BEFORE);
232 #endif
233
234 INIT_ERROR_CHECK(KeepCapability(service) == 0, return INIT_EKEEPCAP,
235 "Service error %d %s, failed to set keep capability.", errno, service->name);
236
237 INIT_ERROR_CHECK(ServiceSetGid(service) == SERVICE_SUCCESS, return INIT_EGIDSET,
238 "Service error %d %s, failed to set gid.", errno, service->name);
239
240 // set seccomp policy before setuid
241 INIT_ERROR_CHECK(SetSystemSeccompPolicy(service) == SERVICE_SUCCESS, return INIT_ESECCOMP,
242 "Service error %d %s, failed to set system seccomp policy.", errno, service->name);
243
244 if (service->servPerm.uID != 0) {
245 INIT_ERROR_CHECK(setuid(service->servPerm.uID) == 0, return INIT_EUIDSET,
246 "Service error %d %s, failed to set uid.", errno, service->name);
247 } else {
248 if (service->servPerm.capsCnt != 0) {
249 DropCapability(service);
250 }
251 }
252
253 struct __user_cap_header_struct capHeader;
254 capHeader.version = _LINUX_CAPABILITY_VERSION_3;
255 capHeader.pid = 0;
256 struct __user_cap_data_struct capData[CAP_NUM] = {};
257 for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
258 if (service->servPerm.caps[i] == FULL_CAP) {
259 for (int j = 0; j < CAP_NUM; ++j) {
260 capData[j].effective = FULL_CAP;
261 capData[j].permitted = FULL_CAP;
262 capData[j].inheritable = FULL_CAP;
263 }
264 break;
265 }
266 capData[CAP_TO_INDEX(service->servPerm.caps[i])].effective |= CAP_TO_MASK(service->servPerm.caps[i]);
267 capData[CAP_TO_INDEX(service->servPerm.caps[i])].permitted |= CAP_TO_MASK(service->servPerm.caps[i]);
268 capData[CAP_TO_INDEX(service->servPerm.caps[i])].inheritable |= CAP_TO_MASK(service->servPerm.caps[i]);
269 }
270
271 INIT_ERROR_CHECK(capset(&capHeader, capData) == 0, return SERVICE_FAILURE,
272 "capset failed for service: %s, error: %d", service->name, errno);
273 for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
274 if (service->servPerm.caps[i] == FULL_CAP) {
275 int ret = SetAllAmbientCapability();
276 INIT_ERROR_CHECK(ret == 0, return INIT_ECAP,
277 "Service error %d %s, failed to set ambient capability.", errno, service->name);
278 return 0;
279 }
280 INIT_ERROR_CHECK(SetAmbientCapability(service->servPerm.caps[i]) == 0, return INIT_ECAP,
281 "Service error %d %s, failed to set ambient capability.", errno, service->name);
282 }
283 #if defined(ENABLE_HOOK_MGR)
284 /*
285 * service set Perms hooks
286 */
287 ServiceHookExecute(service->name, NULL, INIT_SERVICE_SET_PERMS);
288 #endif
289 return SERVICE_SUCCESS;
290 }
291
WritePid(const Service * service)292 static int WritePid(const Service *service)
293 {
294 pid_t childPid = getpid();
295 for (int i = 0; i < service->writePidArgs.count; i++) {
296 if (service->writePidArgs.argv[i] == NULL) {
297 continue;
298 }
299 FILE *fd = NULL;
300 char *realPath = GetRealPath(service->writePidArgs.argv[i]);
301 if (realPath != NULL) {
302 fd = fopen(realPath, "wb");
303 } else {
304 fd = fopen(service->writePidArgs.argv[i], "wb");
305 }
306 if (fd != NULL) {
307 INIT_CHECK_ONLY_ELOG((int)fprintf(fd, "%d", childPid) > 0,
308 "Failed to write %s pid:%d", service->writePidArgs.argv[i], childPid);
309 (void)fclose(fd);
310 } else {
311 INIT_LOGE("Failed to open realPath: %s %s errno:%d.", realPath, service->writePidArgs.argv[i], errno);
312 }
313 if (realPath != NULL) {
314 free(realPath);
315 }
316 INIT_LOGV("ServiceStart writepid filename=%s, childPid=%d, ok", service->writePidArgs.argv[i], childPid);
317 }
318 return SERVICE_SUCCESS;
319 }
320
CloseServiceFds(Service * service,bool needFree)321 void CloseServiceFds(Service *service, bool needFree)
322 {
323 INIT_ERROR_CHECK(service != NULL, return, "Service null");
324 INIT_LOGI("Closing service \' %s \' fds", service->name);
325 // fdCount > 0, There is no reason fds is NULL
326 if (service->fdCount != 0) {
327 size_t fdCount = service->fdCount;
328 int *fds = service->fds;
329 for (size_t i = 0; i < fdCount; i++) {
330 INIT_LOGV("Closing fd: %d", fds[i]);
331 if (fds[i] != -1) {
332 close(fds[i]);
333 fds[i] = -1;
334 }
335 }
336 }
337 service->fdCount = 0;
338 if (needFree && service->fds != NULL) {
339 free(service->fds);
340 service->fds = NULL;
341 }
342 }
343
PublishHoldFds(Service * service)344 static int PublishHoldFds(Service *service)
345 {
346 INIT_ERROR_CHECK(service != NULL, return INIT_EPARAMETER, "Publish hold fds with invalid service");
347 if (service->fdCount == 0 || service->fds == NULL) {
348 return 0;
349 }
350 char fdBuffer[MAX_FD_HOLDER_BUFFER] = {};
351 char envName[MAX_BUFFER_LEN] = {};
352 int ret = snprintf_s(envName, MAX_BUFFER_LEN, MAX_BUFFER_LEN - 1, ENV_FD_HOLD_PREFIX"%s", service->name);
353 INIT_ERROR_CHECK(ret >= 0, return INIT_EFORMAT,
354 "Service error %d %s, failed to format string for publish", ret, service->name);
355
356 size_t pos = 0;
357 for (size_t i = 0; i < service->fdCount; i++) {
358 int fd = dup(service->fds[i]);
359 if (fd < 0) {
360 INIT_LOGW("Service warning %d %s, failed to dup fd for publish", errno, service->name);
361 continue;
362 }
363 ret = snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1, "%d ", fd);
364 INIT_ERROR_CHECK(ret >= 0, return INIT_EFORMAT,
365 "Service error %d %s, failed to format fd for publish", ret, service->name);
366 pos += (size_t)ret;
367 }
368 fdBuffer[pos - 1] = '\0'; // Remove last ' '
369 INIT_LOGI("Service %s publish fd [%s]", service->name, fdBuffer);
370 return setenv(envName, fdBuffer, 1);
371 }
372
BindCpuCore(Service * service)373 static int BindCpuCore(Service *service)
374 {
375 if (service == NULL || service->cpuSet == NULL) {
376 return SERVICE_SUCCESS;
377 }
378 if (CPU_COUNT(service->cpuSet) == 0) {
379 return SERVICE_SUCCESS;
380 }
381 #ifndef __LITEOS_A__
382 int pid = getpid();
383 INIT_ERROR_CHECK(sched_setaffinity(pid, sizeof(cpu_set_t), service->cpuSet) == 0,
384 return SERVICE_FAILURE, "%s set affinity between process(pid=%d) with CPU's core failed", service->name, pid);
385 INIT_LOGI("%s set affinity between process(pid=%d) with CPU's core successfully", service->name, pid);
386 #endif
387 return SERVICE_SUCCESS;
388 }
389
ClearEnvironment(Service * service)390 static void ClearEnvironment(Service *service)
391 {
392 if (strcmp(service->name, "appspawn") != 0 && strcmp(service->name, "nwebspawn") != 0) {
393 sigset_t mask;
394 sigemptyset(&mask);
395 sigaddset(&mask, SIGCHLD);
396 sigaddset(&mask, SIGTERM);
397 sigprocmask(SIG_UNBLOCK, &mask, NULL);
398 }
399 return;
400 }
401
SetServiceEnv(Service * service)402 static void SetServiceEnv(Service *service)
403 {
404 INIT_CHECK(service->env != NULL, return);
405 for (int i = 0; i < service->envCnt; i++) {
406 if (strlen(service->env[i].name) > 0 && strlen(service->env[i].value) > 0) {
407 int ret = setenv(service->env[i].name, service->env[i].value, 1);
408 INIT_CHECK_ONLY_ELOG(ret != 0, "set service:%s env:%s failed! err=%d",
409 service->name, service->env[i].name, errno);
410 }
411 }
412 }
413
InitServiceProperties(Service * service,const ServiceArgs * pathArgs)414 static int InitServiceProperties(Service *service, const ServiceArgs *pathArgs)
415 {
416 INIT_ERROR_CHECK(service != NULL, return -1, "Invalid parameter.");
417 int ret = SetServiceEnterSandbox(service, pathArgs->argv[0]);
418 if (ret != 0) {
419 INIT_LOGW("Service warning %d %s, failed to enter sandbox.", ret, service->name);
420 service->lastErrno = INIT_ESANDBOX;
421 }
422 ret = SetAccessToken(service);
423 if (ret != 0) {
424 INIT_LOGW("Service warning %d %s, failed to set access token.", ret, service->name);
425 service->lastErrno = INIT_EACCESSTOKEN;
426 }
427
428 SetServiceEnv(service);
429
430 // deal start job
431 if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
432 DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
433 INIT_LOGI("Deal service %s job end", service->name);
434 }
435 ClearEnvironment(service);
436 if (!IsOnDemandService(service)) {
437 INIT_ERROR_CHECK(CreateSocketForService(service) == 0, service->lastErrno = INIT_ESOCKET;
438 return INIT_ESOCKET, "Service error %d %s, failed to create service socket.", errno, service->name);
439 }
440 SetSocketEnvForService(service);
441 INIT_ERROR_CHECK(CreateServiceFile(service) == 0, service->lastErrno = INIT_EFILE;
442 return INIT_EFILE, "Service error %d %s, failed to create service file.", errno, service->name);
443
444 if ((service->attribute & SERVICE_ATTR_CONSOLE)) {
445 INIT_ERROR_CHECK(OpenConsole() == 0, service->lastErrno = INIT_ECONSOLE;
446 return INIT_ECONSOLE, "Service error %d %s, failed to open console.", errno, service->name);
447 }
448 if ((service->attribute & SERVICE_ATTR_KMSG)) {
449 OpenKmsg();
450 }
451
452 INIT_ERROR_CHECK(PublishHoldFds(service) == 0, service->lastErrno = INIT_EHOLDER;
453 return INIT_EHOLDER, "Service error %d %s, failed to publish fd", errno, service->name);
454
455 INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS,
456 "Service warning %d %s, failed to publish fd", errno, service->name);
457
458 // write pid
459 INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, service->lastErrno = INIT_EWRITEPID;
460 return INIT_EWRITEPID, "Service error %d %s, failed to write pid.", errno, service->name);
461
462 // permissions
463 ret = SetPerms(service);
464 INIT_ERROR_CHECK(ret == SERVICE_SUCCESS, service->lastErrno = ret;
465 return ret, "Service error %d %s, failed to set permissions.", ret, service->name);
466
467 PluginExecCmdByName("setServiceContent", service->name);
468 return 0;
469 }
470
EnterServiceSandbox(Service * service)471 void EnterServiceSandbox(Service *service)
472 {
473 INIT_ERROR_CHECK(InitServiceProperties(service, &service->pathArgs) == 0, return, "Failed init service property");
474 if (service->importance != 0) {
475 if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
476 INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
477 service->name, service->importance, errno);
478 _exit(0x7f); // 0x7f: user specified
479 }
480 }
481 #ifndef STARTUP_INIT_TEST
482 char *argv[] = { (char *)"/bin/sh", NULL };
483 INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0,
484 "service %s execv sh failed! err %d.", service->name, errno);
485 _exit(PROCESS_EXIT_CODE);
486 #endif
487 }
488
489 #ifdef IS_DEBUG_VERSION
ServiceNeedDebug(char * name)490 static bool ServiceNeedDebug(char *name)
491 {
492 char nameValue[PARAM_VALUE_LEN_MAX] = {0};
493 unsigned int nameLen = PARAM_VALUE_LEN_MAX;
494 // specify process debugging: param set llvm.debug.service.name "service name"
495 if (SystemReadParam("llvm.debug.service.name", nameValue, &nameLen) == 0) {
496 if (strcmp(nameValue, name) == 0) {
497 return true;
498 }
499 }
500
501 char debugValue[PARAM_VALUE_LEN_MAX] = {0};
502 unsigned int debugLen = PARAM_VALUE_LEN_MAX;
503 // multi process debugging: param set llvm.debug.service.all 1
504 if (SystemReadParam("llvm.debug.service.all", debugValue, &debugLen) == 0) {
505 if (strcmp(debugValue, "1") == 0) {
506 return true;
507 }
508 }
509 return false;
510 }
511
IsDebuggableVersion(void)512 static bool IsDebuggableVersion(void)
513 {
514 char secureValue[PARAM_VALUE_LEN_MAX] = {0};
515 unsigned int secureLen = PARAM_VALUE_LEN_MAX;
516 char debugValue[PARAM_VALUE_LEN_MAX] = {0};
517 unsigned int debugLen = PARAM_VALUE_LEN_MAX;
518 // the image is debuggable only when secureValue is 0 and debugValue is 1
519 if (SystemReadParam("const.secure", secureValue, &secureLen) == 0 &&
520 SystemReadParam("const.debuggable", debugValue, &debugLen) == 0) {
521 if (strcmp(secureValue, "0") == 0 &&
522 strcmp(debugValue, "1") == 0) {
523 return true;
524 }
525 }
526 return false;
527 }
528
CheckTraceStatus(void)529 static int32_t CheckTraceStatus(void)
530 {
531 int fd = open("/proc/self/status", O_RDONLY);
532 if (fd == -1) {
533 INIT_LOGE("lldb: open /proc/self/status error: %{public}d", errno);
534 return (-errno);
535 }
536
537 char data[1024] = { 0 }; // 1024 data len
538 ssize_t dataNum = read(fd, data, sizeof(data));
539 if (close(fd) < 0) {
540 INIT_LOGE("lldb: close fd error: %{public}d", errno);
541 return (-errno);
542 }
543
544 if (dataNum <= 0) {
545 INIT_LOGE("lldb: fail to read data");
546 return -1;
547 }
548
549 const char* tracerPid = "TracerPid:\t";
550 data[1023] = '\0'; // 1023 data last position
551 char *traceStr = strstr(data, tracerPid);
552 if (traceStr == NULL) {
553 INIT_LOGE("lldb: fail to find %{public}s", tracerPid);
554 return -1;
555 }
556 char *separator = strchr(traceStr, '\n');
557 if (separator == NULL) {
558 INIT_LOGE("lldb: fail to find line break");
559 return -1;
560 }
561
562 int len = separator - traceStr - strlen(tracerPid);
563 char pid = *(traceStr + strlen(tracerPid));
564 if (len > 1 || pid != '0') {
565 return 0;
566 }
567 return -1;
568 }
569
WaitForDebugger(void)570 static int32_t WaitForDebugger(void)
571 {
572 uint32_t count = 0;
573 while (CheckTraceStatus() != 0) {
574 usleep(1000 * 100); // sleep 1000 * 100 microsecond
575 count++;
576 // remind users to connect to the debugger every 60 * 10 times
577 if (count % (10 * 60) == 0) {
578 INIT_LOGI("lldb: wait for debugger, please attach the process");
579 count = 0;
580 }
581 }
582 return 0;
583 }
584 #endif
585
CloseOnDemandServiceFdForOtherService(Service * service)586 static void CloseOnDemandServiceFdForOtherService(Service *service)
587 {
588 ServiceSocket *tmpSockNode = GetOnDemandSocketList();
589 while (tmpSockNode != NULL) {
590 if (tmpSockNode->service != service) {
591 ServiceSocket *tmpCloseSocket = tmpSockNode;
592 // If the service is not the OnDemand service itself, will close the OnDemand service socket fd
593 while (tmpCloseSocket != NULL) {
594 close(tmpCloseSocket->sockFd);
595 tmpCloseSocket = tmpCloseSocket->next;
596 }
597 }
598 tmpSockNode = tmpSockNode->nextNode;
599 }
600 }
601
RunChildProcess(Service * service,ServiceArgs * pathArgs)602 static void RunChildProcess(Service *service, ServiceArgs *pathArgs)
603 {
604 // set selinux label by context
605 if (service->context.type != INIT_CONTEXT_MAIN && SetSubInitContext(&service->context, service->name) != 0) {
606 service->lastErrno = INIT_ECONTENT;
607 }
608
609 CloseOnDemandServiceFdForOtherService(service);
610
611 #ifdef IS_DEBUG_VERSION
612 // only the image is debuggable and need debug, then wait for debugger
613 if (ServiceNeedDebug(service->name) && IsDebuggableVersion()) {
614 WaitForDebugger();
615 }
616 #endif
617 #ifdef INIT_ASAN
618 CloseStdio();
619 #endif
620 // fail must exit sub process
621 int ret = InitServiceProperties(service, pathArgs);
622 INIT_ERROR_CHECK(ret == 0,
623 _exit(service->lastErrno), "Service error %d %s, failed to set properties", ret, service->name);
624
625 (void)ServiceExec(service, pathArgs);
626 _exit(service->lastErrno);
627 }
628
IsServiceInvalid(Service * service,ServiceArgs * pathArgs)629 static int IsServiceInvalid(Service *service, ServiceArgs *pathArgs)
630 {
631 if (service->attribute & SERVICE_ATTR_INVALID) {
632 INIT_LOGE("ServiceStart invalid:%s", service->name);
633 return SERVICE_FAILURE;
634 }
635 struct stat pathStat = { 0 };
636 service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
637 if (stat(pathArgs->argv[0], &pathStat) != 0) {
638 service->attribute |= SERVICE_ATTR_INVALID;
639 service->lastErrno = INIT_EPATH;
640 INIT_LOGE("ServiceStart pathArgs invalid, please check %s,%s", service->name, service->pathArgs.argv[0]);
641 return SERVICE_FAILURE;
642 }
643 return SERVICE_SUCCESS;
644 }
645
ServiceStart(Service * service,ServiceArgs * pathArgs)646 int ServiceStart(Service *service, ServiceArgs *pathArgs)
647 {
648 INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "ServiceStart failed! null ptr.");
649 INIT_INFO_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "ServiceStart already started:%s", service->name);
650 INIT_ERROR_CHECK(pathArgs != NULL && pathArgs->count > 0,
651 return SERVICE_FAILURE, "ServiceStart pathArgs is NULL:%s", service->name);
652 struct timespec startingTime;
653 clock_gettime(CLOCK_REALTIME, &startingTime);
654 INIT_LOGI("ServiceStart starting:%s", service->name);
655 if (IsServiceInvalid(service, pathArgs) != 0) {
656 INIT_LOGE("IsServiceInvalid falied: %s", service->name);
657 return SERVICE_FAILURE;
658 }
659 #if defined(ENABLE_HOOK_MGR)
660 // before service fork hooks
661 ServiceHookExecute(service->name, NULL, INIT_SERVICE_FORK_BEFORE);
662 #endif
663 // pre-start job
664 if (service->serviceJobs.jobsName[JOB_PRE_START] != NULL) {
665 DoJobNow(service->serviceJobs.jobsName[JOB_PRE_START]);
666 }
667 struct timespec prefork;
668 clock_gettime(CLOCK_REALTIME, &prefork);
669 int pid = fork();
670 if (pid == 0) {
671 RunChildProcess(service, pathArgs);
672 } else if (pid < 0) {
673 INIT_LOGE("ServiceStart error failed to fork %d, %s", errno, service->name);
674 service->lastErrno = INIT_EFORK;
675 return SERVICE_FAILURE;
676 }
677 struct timespec startedTime;
678 clock_gettime(CLOCK_REALTIME, &startedTime);
679 INIT_LOGI("ServiceStart started info %s(pid %d uid %d)", service->name, pid, service->servPerm.uID);
680 INIT_LOGI("starttime:%ld-%ld,preforktime:%ld-%ld,startedtime:%ld-%ld",
681 startingTime.tv_sec, startingTime.tv_nsec, prefork.tv_sec,
682 prefork.tv_nsec, startedTime.tv_sec, startedTime.tv_nsec);
683 #ifndef OHOS_LITE
684 if (!IsOnDemandService(service)) {
685 ReportServiceStart(service->name, pid);
686 }
687 #endif
688 service->pid = pid;
689 #ifndef OHOS_LITE
690 (void)ProcessServiceAdd(service);
691 #endif
692 NotifyServiceChange(service, SERVICE_STARTED);
693 #if defined(ENABLE_HOOK_MGR)
694 // after service fork hooks
695 ServiceHookExecute(service->name, (const char *)&pid, INIT_SERVICE_FORK_AFTER);
696 #endif
697 return SERVICE_SUCCESS;
698 }
699
ServiceStop(Service * service)700 int ServiceStop(Service *service)
701 {
702 INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "stop service failed! null ptr.");
703 NotifyServiceChange(service, SERVICE_STOPPING);
704 if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
705 DoJobNow(service->serviceJobs.jobsName[JOB_ON_STOP]);
706 }
707 service->attribute &= ~SERVICE_ATTR_NEED_RESTART;
708 service->attribute |= SERVICE_ATTR_NEED_STOP;
709 if (service->pid <= 0) {
710 return SERVICE_SUCCESS;
711 }
712 CloseServiceSocket(service);
713 CloseServiceFile(service->fileCfg);
714 // Service stop means service is killed by init or command(i.e stop_service) or system is rebooting
715 // There is no reason still to hold fds
716 if (service->fdCount != 0) {
717 CloseServiceFds(service, true);
718 }
719
720 if (IsServiceWithTimerEnabled(service)) {
721 ServiceStopTimer(service);
722 }
723 INIT_ERROR_CHECK(kill(service->pid, GetKillServiceSig(service->name)) == 0, return SERVICE_FAILURE,
724 "stop service %s pid %d failed! err %d.", service->name, service->pid, errno);
725 INIT_LOGI("stop service %s, pid %d.", service->name, service->pid);
726 service->pid = -1;
727 NotifyServiceChange(service, SERVICE_STOPPED);
728 return SERVICE_SUCCESS;
729 }
730
CalculateCrashTime(Service * service,int crashTimeLimit,int crashCountLimit)731 static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCountLimit)
732 {
733 INIT_ERROR_CHECK(service != NULL && crashTimeLimit > 0 && crashCountLimit > 0,
734 return false, "input params error.");
735 struct timespec curTime = {0};
736 (void)clock_gettime(CLOCK_MONOTONIC, &curTime);
737 struct timespec crashTime = {service->firstCrashTime, 0};
738 if (service->crashCnt == 0) {
739 service->firstCrashTime = (uint32_t)curTime.tv_sec;
740 ++service->crashCnt;
741 if (service->crashCnt == crashCountLimit) {
742 return false;
743 }
744 } else if (IntervalTime(&crashTime, &curTime) > (uint32_t)crashTimeLimit) {
745 service->firstCrashTime = (uint32_t)curTime.tv_sec;
746 service->crashCnt = 1;
747 } else {
748 ++service->crashCnt;
749 if (service->crashCnt >= crashCountLimit) {
750 return false;
751 }
752 }
753 return true;
754 }
755
ExecRestartCmd(Service * service)756 static int ExecRestartCmd(Service *service)
757 {
758 INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr.");
759 if (service->restartArg == NULL) {
760 return SERVICE_SUCCESS;
761 }
762 for (int i = 0; i < service->restartArg->cmdNum; i++) {
763 INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent);
764 DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent, NULL);
765 }
766 free(service->restartArg);
767 service->restartArg = NULL;
768 return SERVICE_SUCCESS;
769 }
770
CheckServiceSocket(Service * service)771 static void CheckServiceSocket(Service *service)
772 {
773 if (service->socketCfg == NULL) {
774 return;
775 }
776 ServiceSocket *tmpSock = service->socketCfg;
777 while (tmpSock != NULL) {
778 if (tmpSock->sockFd <= 0) {
779 INIT_LOGE("Invalid socket %s for service", service->name);
780 tmpSock = tmpSock->next;
781 }
782 AddSocketWatcher(&tmpSock->watcher, service, tmpSock->sockFd);
783 tmpSock = tmpSock->next;
784 }
785 return;
786 }
787
IsDebugMode()788 static bool IsDebugMode()
789 {
790 char secureValue[PARAM_VALUE_LEN_MAX] = {0};
791 unsigned int secureLen = PARAM_VALUE_LEN_MAX;
792 char debugValue[PARAM_VALUE_LEN_MAX] = {0};
793 unsigned int debugLen = PARAM_VALUE_LEN_MAX;
794 // the image is debuggable only when secureValue is 0 and debugValue is 1
795 if (SystemReadParam("const.secure", secureValue, &secureLen) == 0 &&
796 SystemReadParam("const.debuggable", debugValue, &debugLen) == 0) {
797 if (strcmp(secureValue, "0") == 0 &&
798 strcmp(debugValue, "1") == 0) {
799 return true;
800 }
801 }
802 return false;
803 }
804
CheckOndemandService(Service * service)805 static void CheckOndemandService(Service *service)
806 {
807 CheckServiceSocket(service);
808 if (strcmp(service->name, "console") == 0 && IsDebugMode()) {
809 INIT_LOGI("Watch console service in debug mode");
810 if (WatchConsoleDevice(service) < 0) {
811 INIT_LOGE("Failed to watch console service after it exit, mark console service invalid");
812 service->attribute |= SERVICE_ATTR_INVALID;
813 }
814 }
815 }
816
ServiceReapHookExecute(Service * service)817 static void ServiceReapHookExecute(Service *service)
818 {
819 #if defined(ENABLE_HOOK_MGR)
820 HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_REAP, (void*)service, NULL);
821 #endif
822 }
823
ServiceReap(Service * service)824 void ServiceReap(Service *service)
825 {
826 INIT_CHECK(service != NULL, return);
827 INIT_LOGI("ServiceReap info %s pid %d.", service->name, service->pid);
828 NotifyServiceChange(service, SERVICE_STOPPED);
829 int tmp = service->pid;
830 service->pid = -1;
831
832 if (service->attribute & SERVICE_ATTR_INVALID) {
833 INIT_LOGE("ServiceReap error invalid service %s", service->name);
834 return;
835 }
836
837 // If the service set timer
838 // which means the timer handler will start the service
839 // Init should not start it automatically.
840 INIT_CHECK(IsServiceWithTimerEnabled(service) == 0, return);
841 if (!IsOnDemandService(service)) {
842 CloseServiceSocket(service);
843 }
844 CloseServiceFile(service->fileCfg);
845 // stopped by system-init itself, no need to restart even if it is not one-shot service
846 if (service->attribute & SERVICE_ATTR_NEED_STOP) {
847 service->attribute &= (~SERVICE_ATTR_NEED_STOP);
848 service->crashCnt = 0;
849 return;
850 }
851
852 // for one-shot service
853 if (service->attribute & SERVICE_ATTR_ONCE) {
854 // no need to restart
855 if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
856 service->attribute &= (~SERVICE_ATTR_NEED_STOP);
857 return;
858 }
859 // the service could be restart even if it is one-shot service
860 }
861
862 if (service->attribute & SERVICE_ATTR_PERIOD) { //period
863 ServiceStartTimer(service, service->period);
864 return;
865 }
866
867 // service no need to restart if it is an ondemand service.
868 if (IsOnDemandService(service)) {
869 CheckOndemandService(service);
870 return;
871 }
872
873 if (service->attribute & SERVICE_ATTR_CRITICAL) { // critical
874 if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
875 INIT_LOGE("ServiceReap error critical service crashed %s %d", service->name, service->crashCount);
876 service->pid = tmp;
877 ServiceReapHookExecute(service);
878 service->pid = -1;
879 ExecReboot("panic");
880 }
881 } else if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
882 if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
883 INIT_LOGI("ServiceReap start failed! %s will reStart %d second later", service->name, service->crashTime);
884 service->crashCnt = 0;
885 ServiceReStartTimer(service, DEF_CRASH_TIME);
886 return;
887 }
888 }
889
890 int ret = ExecRestartCmd(service);
891 INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "ServiceReap Failed to exec restartArg for %s", service->name);
892
893 if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
894 DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
895 }
896 ret = ServiceStart(service, &service->pathArgs);
897 INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "ServiceReap ServiceStart failed %s", service->name);
898 service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
899 }
900
UpdaterServiceFds(Service * service,int * fds,size_t fdCount)901 int UpdaterServiceFds(Service *service, int *fds, size_t fdCount)
902 {
903 if (service == NULL || fds == NULL) {
904 INIT_LOGE("Invalid service info or fds");
905 return -1;
906 }
907
908 if (fdCount == 0) {
909 INIT_LOGE("Update service fds with fdCount is 0, ignore.");
910 return 0;
911 }
912
913 // if service->fds is NULL, allocate new memory to hold the fds
914 // else if service->fds is not NULL, we will try to override it.
915 // There are two cases:
916 // 1) service->fdCount != fdCount:
917 // It is not easy to re-use the memory of service->fds, so we have to free the memory first
918 // then re-allocate memory to store new fds
919 // 2) service->fdCount == fdCount
920 // A situation we happy to meet, just override it.
921
922 int ret = 0;
923 if (service->fdCount == fdCount) {
924 // case 2
925 CloseServiceFds(service, false);
926 if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
927 INIT_LOGE("Failed to copy fds to service");
928 // Something wrong happened, maybe service->fds is broken, clear it.
929 free(service->fds);
930 service->fds = NULL;
931 service->fdCount = 0;
932 ret = -1;
933 } else {
934 service->fdCount = fdCount;
935 }
936 } else {
937 if (service->fdCount > 0) {
938 // case 1
939 CloseServiceFds(service, true);
940 }
941 INIT_ERROR_CHECK(fdCount <= MAX_HOLD_FDS, return -1, "Invalid fdCount %d", fdCount);
942 service->fds = calloc(fdCount + 1, sizeof(int));
943 if (service->fds == NULL) {
944 INIT_LOGE("Service \' %s \' failed to allocate memory for fds", service->name);
945 ret = -1;
946 } else {
947 if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
948 INIT_LOGE("Failed to copy fds to service");
949 // Something wrong happened, maybe service->fds is broken, clear it.
950 free(service->fds);
951 service->fds = NULL;
952 service->fdCount = 0;
953 return -1;
954 } else {
955 service->fdCount = fdCount;
956 }
957 }
958 }
959 INIT_LOGI("Hold fd for service \' %s \' done", service->name);
960 return ret;
961 }
962
ServiceStopTimer(Service * service)963 void ServiceStopTimer(Service *service)
964 {
965 INIT_ERROR_CHECK(service != NULL, return, "Stop timer with invalid service");
966 if (IsServiceWithTimerEnabled(service)) {
967 // Stop timer first
968 if (service->timer) {
969 LE_StopTimer(LE_GetDefaultLoop(), service->timer);
970 }
971 service->timer = NULL;
972 DisableServiceTimer(service);
973 }
974 }
975
ServiceTimerStartProcess(const TimerHandle handler,void * context)976 static void ServiceTimerStartProcess(const TimerHandle handler, void *context)
977 {
978 UNUSED(handler);
979 Service *service = (Service *)context;
980
981 if (service == NULL) {
982 INIT_LOGE("Service timer process with invalid service");
983 return;
984 }
985
986 // OK, service is ready to start.
987 // Before start the service, stop service timer.
988 // make sure it will not enter timer handler next time.
989 ServiceStopTimer(service);
990 int ret = ServiceStart(service, &service->pathArgs);
991 if (ret != SERVICE_SUCCESS) {
992 INIT_LOGE("Start service \' %s \' in timer failed", service->name);
993 }
994 }
995
ServiceTimerReStartProcess(const TimerHandle handler,void * context)996 static void ServiceTimerReStartProcess(const TimerHandle handler, void *context)
997 {
998 UNUSED(handler);
999 Service *service = (Service *)context;
1000
1001 if (service == NULL) {
1002 INIT_LOGE("Service timer process with invalid service");
1003 return;
1004 }
1005
1006 // OK, service is ready to start.
1007 // Before start the service, stop service timer.
1008 // make sure it will not enter timer handler next time.
1009 ServiceStopTimer(service);
1010
1011 if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
1012 DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
1013 }
1014 int ret = ServiceStart(service, &service->pathArgs);
1015 if (ret != SERVICE_SUCCESS) {
1016 INIT_LOGE("Start service \' %s \' in timer failed", service->name);
1017 }
1018 }
1019
ServiceStartTimer(Service * service,uint64_t timeout)1020 void ServiceStartTimer(Service *service, uint64_t timeout)
1021 {
1022 bool oldTimerClean = false;
1023 INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
1024 // If the service already set a timer.
1025 // And a new request coming. close it and create a new one.
1026 if (IsServiceWithTimerEnabled(service)) {
1027 ServiceStopTimer(service);
1028 oldTimerClean = true;
1029 }
1030 LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerStartProcess,
1031 (void *)service);
1032 if (status != LE_SUCCESS) {
1033 INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
1034 if (oldTimerClean) {
1035 INIT_LOGE("previous timer is cleared");
1036 }
1037 return;
1038 }
1039 status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
1040 INIT_ERROR_CHECK(status == LE_SUCCESS, return,
1041 "Start service timer for service \' %s \' failed, status = %d", service->name, status);
1042 EnableServiceTimer(service);
1043 }
1044
ServiceReStartTimer(Service * service,uint64_t timeout)1045 void ServiceReStartTimer(Service *service, uint64_t timeout)
1046 {
1047 bool oldTimerClean = false;
1048 INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
1049 // If the service already set a timer.
1050 // And a new request coming. close it and create a new one.
1051 if (IsServiceWithTimerEnabled(service)) {
1052 ServiceStopTimer(service);
1053 oldTimerClean = true;
1054 }
1055 LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerReStartProcess,
1056 (void *)service);
1057 if (status != LE_SUCCESS) {
1058 INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
1059 if (oldTimerClean) {
1060 INIT_LOGE("previous timer is cleared");
1061 }
1062 return;
1063 }
1064 status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
1065 INIT_ERROR_CHECK(status == LE_SUCCESS, return,
1066 "Start service timer for service \' %s \' failed, status = %d", service->name, status);
1067 EnableServiceTimer(service);
1068 }
1069