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