1 /*
2 * Copyright (c) 2021-2024 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_cmds.h"
16
17 #include <dlfcn.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <net/if.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/mount.h>
26 #include <sys/resource.h>
27 #include <sys/stat.h>
28 #include <sys/syscall.h>
29 #include <sys/sysmacros.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32 #include <linux/module.h>
33
34 #include "bootstage.h"
35 #include "fs_manager/fs_manager.h"
36 #include "init_cmdexecutor.h"
37 #include "init_jobs_internal.h"
38 #include "init_log.h"
39 #include "init_param.h"
40 #include "init_service_manager.h"
41 #include "init_utils.h"
42 #include "sandbox.h"
43 #include "sandbox_namespace.h"
44 #include "securec.h"
45 #include "fscrypt_utils.h"
46
47 #ifdef SUPPORT_PROFILER_HIDEBUG
48 #include <hidebug_base.h>
49 #endif
50
51 #define FSCRYPT_POLICY_BUF_SIZE (60)
52 #define DECIMAL 10
53 #define OCTAL 8
54 #define BOOT_DETECTOR_IOCTL_BASE 'B'
55 #define SET_SHUT_STAGE _IOW(BOOT_DETECTOR_IOCTL_BASE, 106, int)
56 #define SHUT_STAGE_FRAMEWORK_START 1
57
GetParamValue(const char * symValue,unsigned int symLen,char * paramValue,unsigned int paramLen)58 int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen)
59 {
60 INIT_CHECK_RETURN_VALUE((symValue != NULL) && (paramValue != NULL) && (paramLen != 0), -1);
61 char tmpName[PARAM_NAME_LEN_MAX] = { 0 };
62 int ret;
63 uint32_t curr = 0;
64 char *start = (char *)symValue;
65 if (symLen > strlen(symValue)) {
66 return -1;
67 }
68 char *end = (char *)symValue + symLen;
69 do {
70 char *begin = strchr(start, '$');
71 if (begin == NULL || begin >= end) { // not has '$' copy the original string
72 ret = strncpy_s(paramValue + curr, paramLen - curr, start, symLen);
73 INIT_ERROR_CHECK(ret == EOK, return -1, "Failed to copy start %s", start);
74 break;
75 } else {
76 ret = memcpy_s(paramValue + curr, paramLen - curr, start, begin - start);
77 INIT_ERROR_CHECK(ret == 0, return -1, "Failed to copy first value %s", symValue);
78 curr += begin - start;
79 }
80 while (*begin != '{') {
81 INIT_CHECK_RETURN_VALUE(*begin != '\0', -1);
82 begin++;
83 }
84 begin++;
85 char *left = strchr(begin, '}');
86 INIT_CHECK_RETURN_VALUE(left != NULL, -1);
87
88 // copy param name
89 ret = strncpy_s(tmpName, PARAM_NAME_LEN_MAX, begin, left - begin);
90 INIT_ERROR_CHECK(ret == EOK, return -1, "Invalid param name %s", symValue);
91 if (paramLen < curr) {
92 INIT_LOGE("Failed to get param value over max length");
93 return -1;
94 }
95 uint32_t valueLen = paramLen - curr;
96 ret = SystemReadParam(tmpName, paramValue + curr, &valueLen);
97 INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get param %s", tmpName);
98 curr += valueLen;
99 left++;
100 if ((unsigned int)(left - symValue) >= symLen) {
101 break;
102 }
103 start = left;
104 } while (1);
105 return 0;
106 }
107
SyncExecCommand(int argc,char * const * argv)108 static int SyncExecCommand(int argc, char * const *argv)
109 {
110 INIT_LOGI("Sync exec: %s", argv[0]);
111 pid_t pid = fork();
112 INIT_ERROR_CHECK(!(pid < 0), return -1, "Fork new process to format failed: %d", errno);
113 if (pid == 0) {
114 INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0, "execv %s failed! err %d.", argv[0], errno);
115 exit(-1);
116 }
117 int status;
118 pid_t ret = waitpid(pid, &status, 0);
119 if (ret != pid) {
120 INIT_LOGE("Failed to wait pid %d, errno %d", pid, errno);
121 return -1;
122 }
123 INIT_LOGI("Sync exec: %s result %d %d", argv[0], WEXITSTATUS(status), WIFEXITED(status));
124 return WEXITSTATUS(status);
125 }
126
DoIfup(const struct CmdArgs * ctx)127 static void DoIfup(const struct CmdArgs *ctx)
128 {
129 struct ifreq interface;
130 INIT_ERROR_CHECK(strncpy_s(interface.ifr_name, IFNAMSIZ - 1, ctx->argv[0], strlen(ctx->argv[0])) == EOK,
131 return, "DoIfup failed to copy interface name");
132 INIT_LOGV("interface name: %s", interface.ifr_name);
133
134 int fd = socket(AF_INET, SOCK_DGRAM, 0);
135 INIT_ERROR_CHECK(fd >= 0, return, "DoIfup failed to create socket, err = %d", errno);
136
137 if (ioctl(fd, SIOCGIFFLAGS, &interface) >= 0) {
138 interface.ifr_flags |= IFF_UP;
139 INIT_CHECK_ONLY_ELOG(ioctl(fd, SIOCSIFFLAGS, &interface) >= 0,
140 "DoIfup failed to do ioctl with command \"SIOCSIFFLAGS\", err = %d", errno);
141 }
142 close(fd);
143 }
144
145 // format insmod <ko name> [-f] [options]
DoInsmod(const struct CmdArgs * ctx)146 static void DoInsmod(const struct CmdArgs *ctx)
147 {
148 int index = 0;
149 int flags = 0;
150 char *fileName = NULL;
151 if (ctx->argc > index) {
152 fileName = ctx->argv[index];
153 index++;
154 }
155 INIT_ERROR_CHECK(fileName != NULL, return, "Can not find file name from param %s", ctx->argv[0]);
156 INIT_LOGV("Install mode %s ", fileName);
157 char *realPath = GetRealPath(fileName);
158 INIT_ERROR_CHECK(realPath != NULL, return, "Can not get real file name from param %s", ctx->argv[0]);
159 if (ctx->argc > 1 && ctx->argv[1] != NULL && strcmp(ctx->argv[1], "-f") == 0) { // [-f]
160 flags = MODULE_INIT_IGNORE_VERMAGIC | MODULE_INIT_IGNORE_MODVERSIONS;
161 index++;
162 }
163 char *options = BuildStringFromCmdArg(ctx, index); // [options]
164 int fd = open(realPath, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
165 if (fd >= 0) {
166 int rc = syscall(__NR_finit_module, fd, options, flags);
167 if (rc == -1) {
168 INIT_LOGE("Failed to install kernel module for %s failed options %s err: %d", realPath, options, errno);
169 }
170 }
171 if (options != NULL) {
172 free(options);
173 }
174 if (fd >= 0) {
175 close(fd);
176 }
177 free(realPath);
178 return;
179 }
180
DoSetParam(const struct CmdArgs * ctx)181 static void DoSetParam(const struct CmdArgs *ctx)
182 {
183 INIT_LOGV("set param name: %s, value %s ", ctx->argv[0], ctx->argv[1]);
184 SystemWriteParam(ctx->argv[0], ctx->argv[1]);
185 }
186
DoLoadPersistParams(const struct CmdArgs * ctx)187 static void DoLoadPersistParams(const struct CmdArgs *ctx)
188 {
189 INIT_LOGV("LoadPersistParams");
190 LoadPersistParams();
191 }
192
DoLoadPrivatePersistParams(const struct CmdArgs * ctx)193 static void DoLoadPrivatePersistParams(const struct CmdArgs *ctx)
194 {
195 INIT_LOGV("LoadPersistParams");
196 LoadPrivatePersistParams();
197 HookMgrExecute(GetBootStageHookMgr(), INIT_POST_PERSIST_PARAM_LOAD, NULL, NULL);
198 }
199
DoTriggerCmd(const struct CmdArgs * ctx)200 static void DoTriggerCmd(const struct CmdArgs *ctx)
201 {
202 INIT_LOGV("DoTrigger :%s", ctx->argv[0]);
203 DoTriggerExec(ctx->argv[0]);
204 }
205
DoLoadDefaultParams(const struct CmdArgs * ctx)206 static void DoLoadDefaultParams(const struct CmdArgs *ctx)
207 {
208 int mode = 0;
209 if (ctx->argc > 1 && strcmp(ctx->argv[1], "onlyadd") == 0) {
210 mode = LOAD_PARAM_ONLY_ADD;
211 }
212 INIT_LOGV("DoLoadDefaultParams args : %s %d", ctx->argv[0], mode);
213 LoadDefaultParams(ctx->argv[0], mode);
214 }
215
DoSyncExec(const struct CmdArgs * ctx)216 static void DoSyncExec(const struct CmdArgs *ctx)
217 {
218 // format: syncexec /xxx/xxx/xxx xxx
219 INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return, "DoSyncExec: invalid arguments");
220 SyncExecCommand(ctx->argc, ctx->argv);
221 return;
222 }
223
DoExec(const struct CmdArgs * ctx)224 static void DoExec(const struct CmdArgs *ctx)
225 {
226 // format: exec /xxx/xxx/xxx xxx
227 INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return, "DoExec: invalid arguments");
228 pid_t pid = fork();
229 INIT_ERROR_CHECK(pid >= 0, return, "DoExec: failed to fork child process to exec \"%s\"", ctx->argv[0]);
230
231 if (pid == 0) {
232 OpenHidebug(ctx->argv[0]);
233 int ret = execv(ctx->argv[0], ctx->argv);
234 INIT_CHECK_ONLY_ELOG(ret != -1, "DoExec: execute \"%s\" failed: %d.", ctx->argv[0], errno);
235 _exit(0x7f);
236 }
237 return;
238 }
239
DoSymlink(const struct CmdArgs * ctx)240 static void DoSymlink(const struct CmdArgs *ctx)
241 {
242 // format: symlink /xxx/xxx/xxx /xxx/xxx/xxx
243 int ret = symlink(ctx->argv[0], ctx->argv[1]);
244 if (ret != 0 && errno != EEXIST) {
245 INIT_LOGE("DoSymlink: link %s to %s failed: %d", ctx->argv[0], ctx->argv[1], errno);
246 }
247 }
248
GetDeviceMode(const char * deviceStr)249 static mode_t GetDeviceMode(const char *deviceStr)
250 {
251 switch (*deviceStr) {
252 case 'b':
253 case 'B':
254 return S_IFBLK;
255 case 'c':
256 case 'C':
257 return S_IFCHR;
258 case 'f':
259 case 'F':
260 return S_IFIFO;
261 default:
262 return -1;
263 }
264 }
265
DoMakeNode(const struct CmdArgs * ctx)266 static void DoMakeNode(const struct CmdArgs *ctx)
267 {
268 // format: mknod path b 0644 1 9
269 const int deviceTypePos = 1;
270 const int authorityPos = 2;
271 const int majorDevicePos = 3;
272 const int minorDevicePos = 4;
273 INIT_ERROR_CHECK(access(ctx->argv[1], F_OK), return, "DoMakeNode failed, path has sexisted");
274 mode_t deviceMode = GetDeviceMode(ctx->argv[deviceTypePos]);
275 errno = 0;
276 unsigned int major = strtoul(ctx->argv[majorDevicePos], NULL, DECIMAL);
277 INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[majorDevicePos]);
278 unsigned int minor = strtoul(ctx->argv[minorDevicePos], NULL, DECIMAL);
279 INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[minorDevicePos]);
280 mode_t authority = strtoul(ctx->argv[authorityPos], NULL, OCTAL);
281 INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[authorityPos]);
282 int ret = mknod(ctx->argv[0], deviceMode | authority, makedev(major, minor));
283 if (ret != 0) {
284 INIT_LOGE("DoMakeNode: path: %s failed: %d", ctx->argv[0], errno);
285 }
286 }
287
DoMakeDevice(const struct CmdArgs * ctx)288 static void DoMakeDevice(const struct CmdArgs *ctx)
289 {
290 // format: makedev major minor
291 errno = 0;
292 unsigned int major = strtoul(ctx->argv[0], NULL, DECIMAL);
293 INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[0]);
294 unsigned int minor = strtoul(ctx->argv[1], NULL, DECIMAL);
295 INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[1]);
296 dev_t deviceId = makedev(major, minor);
297 INIT_CHECK_ONLY_ELOG(deviceId >= 0, "DoMakedevice \" major:%s, minor:%s \" failed :%d ", ctx->argv[0],
298 ctx->argv[1], errno);
299 return;
300 }
301
DoMountFstabFileSp(const struct CmdArgs * ctx)302 static void DoMountFstabFileSp(const struct CmdArgs *ctx)
303 {
304 INIT_LOGI("Mount partitions from fstab file \" %s \"", ctx->argv[0]);
305 INIT_TIMING_STAT cmdTimer;
306 (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.startTime);
307 int ret = MountAllWithFstabFile(ctx->argv[0], 0);
308 (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
309 long long diff = InitDiffTime(&cmdTimer);
310 INIT_LOGI("Mount partitions from fstab file \" %s \" finish ret %d", ctx->argv[0], ret);
311 HookMgrExecute(GetBootStageHookMgr(), INIT_MOUNT_STAGE, NULL, NULL);
312 char buffer[PARAM_VALUE_LEN_MAX] = {0};
313 ret = sprintf_s(buffer, PARAM_VALUE_LEN_MAX, "%lld", diff);
314 if (ret <= 0) {
315 INIT_LOGE("Failed to sprintf_s");
316 return;
317 }
318 ret = SystemWriteParam("boot.time.fstab", buffer);
319 INIT_ERROR_CHECK(ret == 0, return, "write param boot.time.fstab failed");
320 }
321
DoMountFstabFile(const struct CmdArgs * ctx)322 static void DoMountFstabFile(const struct CmdArgs *ctx)
323 {
324 INIT_LOGI("Mount partitions from fstab file \" %s \"", ctx->argv[0]);
325 int ret = MountAllWithFstabFile(ctx->argv[0], 0);
326 INIT_LOGI("Mount partitions from fstab file \" %s \" finish ret %d", ctx->argv[0], ret);
327 HookMgrExecute(GetBootStageHookMgr(), INIT_MOUNT_STAGE, NULL, NULL);
328 }
329
DoUmountFstabFile(const struct CmdArgs * ctx)330 static void DoUmountFstabFile(const struct CmdArgs *ctx)
331 {
332 INIT_LOGI("Umount partitions from fstab file \" %s \"", ctx->argv[0]);
333 int rc = UmountAllWithFstabFile(ctx->argv[0]);
334 if (rc < 0) {
335 INIT_LOGE("Run command umount_fstab failed");
336 } else {
337 INIT_LOGI("Umount partitions from fstab done");
338 }
339 }
340
DoRestorecon(const struct CmdArgs * ctx)341 static void DoRestorecon(const struct CmdArgs *ctx)
342 {
343 int ret;
344 INIT_CMD_INFO cmdInfo;
345 cmdInfo.cmdName = "restorecon";
346 cmdInfo.cmdContent = ctx->argv[0];
347 cmdInfo.reserved = NULL;
348 if (ctx->argc > 1) {
349 if (strcmp(ctx->argv[0], "-F") == 0) {
350 cmdInfo.cmdContent = ctx->argv[1];
351 }
352 if (strcmp(ctx->argv[ctx->argc - 1], "--skip-ELX") == 0) {
353 cmdInfo.reserved = ctx->argv[ctx->argc - 1];
354 }
355 }
356
357 HOOK_EXEC_OPTIONS options;
358 options.flags = TRAVERSE_STOP_WHEN_ERROR;
359 options.preHook = NULL;
360 options.postHook = NULL;
361 ret = HookMgrExecute(GetBootStageHookMgr(), INIT_RESTORECON, (void*)(&cmdInfo), (void*)(&options));
362 if (ret == 0) {
363 return;
364 }
365 if (ctx->argc > 1) {
366 if (strcmp(ctx->argv[0], "-F") == 0) {
367 PluginExecCmdByName("restoreContentRecurseForce", ctx->argv[1]);
368 } else if (strcmp(ctx->argv[ctx->argc - 1], "--skip-ELX") == 0) {
369 PluginExecCmdByName("restoreContentRecurseSkipElx", ctx->argv[0]);
370 }
371 } else {
372 PluginExecCmdByName("restoreContentRecurse", ctx->argv[0]);
373 }
374 return;
375 }
376
DoLoadAccessTokenId(const struct CmdArgs * ctx)377 static void DoLoadAccessTokenId(const struct CmdArgs *ctx)
378 {
379 LoadAccessTokenId();
380 }
381
FilterService(const Service * service,const char ** exclude,int size)382 static int FilterService(const Service *service, const char **exclude, int size)
383 {
384 for (int i = 0; i < size; i++) {
385 if (exclude[i] != NULL && strcmp(service->name, exclude[i]) == 0) {
386 return 1;
387 }
388 }
389 return 0;
390 }
391
DoStopAllServices(const struct CmdArgs * ctx)392 static void DoStopAllServices(const struct CmdArgs *ctx)
393 {
394 int flags = SERVICE_ATTR_INVALID;
395 if (ctx->argc >= 1 && strcmp(ctx->argv[0], "true") == 0) {
396 flags |= SERVICE_ATTR_NEEDWAIT;
397 StopAllServices(flags, (const char **)(&ctx->argv[1]), ctx->argc - 1, FilterService);
398 } else {
399 StopAllServices(flags, (const char **)ctx->argv, ctx->argc, FilterService);
400 }
401 return;
402 }
403
DoUmount(const struct CmdArgs * ctx)404 static void DoUmount(const struct CmdArgs *ctx)
405 {
406 INIT_LOGI("DoUmount %s", ctx->argv[0]);
407 MountStatus status = GetMountStatusForMountPoint(ctx->argv[0]);
408 if (status == MOUNT_MOUNTED) {
409 int ret = umount(ctx->argv[0]);
410 if ((ret != 0) && (ctx->argc > 1) && (strcmp(ctx->argv[1], "MNT_FORCE") == 0)) {
411 ret = umount2(ctx->argv[0], MNT_FORCE);
412 }
413 INIT_CHECK_ONLY_ELOG(ret == 0, "Failed to umount %s, errno %d", ctx->argv[0], errno);
414 } else if (status == MOUNT_UMOUNTED) {
415 INIT_LOGI("%s is already umounted", ctx->argv[0]);
416 } else {
417 INIT_LOGE("Failed to get %s mount status", ctx->argv[0]);
418 }
419 }
420
DoRemoveDmDevice(const struct CmdArgs * ctx)421 static void DoRemoveDmDevice(const struct CmdArgs *ctx)
422 {
423 INIT_LOGI("DoRemoveDmDevice %s", ctx->argv[0]);
424 int ret = FsManagerDmRemoveDevice(ctx->argv[0]);
425 if (ret < 0) {
426 INIT_LOGE("Failed to remove dm device %s", ctx->argv[0]);
427 } else {
428 INIT_LOGI("Successed to remove dm device %s", ctx->argv[0]);
429 }
430 }
431
DoMountOneFstabFile(const struct CmdArgs * ctx)432 static void DoMountOneFstabFile(const struct CmdArgs *ctx)
433 {
434 bool required = true;
435 if (ctx->argc > 2 && (strcmp(ctx->argv[2], "0") == 0)) { // 2 : required arg position
436 required = false;
437 }
438 INIT_LOGI("Mount %s from fstab file \" %s \" \" %d \"", ctx->argv[1], ctx->argv[0], (int)required);
439 int ret = MountOneWithFstabFile(ctx->argv[0], ctx->argv[1], required);
440 if (ret < 0) {
441 INIT_LOGE("Failed to mount dm device %d", ret);
442 } else {
443 INIT_LOGI("Successed to mount dm device %d", ret);
444 }
445 }
446
DoSync(const struct CmdArgs * ctx)447 static void DoSync(const struct CmdArgs *ctx)
448 {
449 INIT_LOGI("start sync");
450 sync();
451 }
452
DoTimerStart(const struct CmdArgs * ctx)453 static void DoTimerStart(const struct CmdArgs *ctx)
454 {
455 INIT_LOGI("Timer start service with arg = %s", ctx->argv[0]);
456 char *arg = ctx->argv[0];
457 int count = 0;
458 int expectedCount = 2;
459 char **splitArgs = SplitStringExt(ctx->argv[0], "|", &count, expectedCount);
460 if (splitArgs == NULL) {
461 INIT_LOGE("Call timer_start with invalid arguments");
462 return;
463 }
464
465 if (count != expectedCount) {
466 INIT_LOGE("Call timer_start with unexpected arguments %s", arg);
467 FreeStringVector(splitArgs, count);
468 return;
469 }
470
471 Service *service = GetServiceByName(splitArgs[0]);
472 if (service == NULL) {
473 INIT_LOGE("Cannot find service in timer_start command");
474 FreeStringVector(splitArgs, count);
475 return;
476 }
477
478 errno = 0;
479 uint64_t timeout = strtoull(splitArgs[1], NULL, DECIMAL_BASE);
480 if (errno != 0) {
481 INIT_LOGE("call timer_start with invalid timer");
482 FreeStringVector(splitArgs, count);
483 return;
484 }
485 // not need this anymore , release memory.
486 FreeStringVector(splitArgs, count);
487 ServiceStartTimer(service, timeout);
488 }
489
DoTimerStop(const struct CmdArgs * ctx)490 static void DoTimerStop(const struct CmdArgs *ctx)
491 {
492 INIT_LOGI("Stop service timer with arg = %s", ctx->argv[0]);
493 const char *serviceName = ctx->argv[0];
494 Service *service = GetServiceByName(serviceName);
495 if (service == NULL) {
496 INIT_LOGE("Cannot find service in timer_stop command");
497 return;
498 }
499 ServiceStopTimer(service);
500 }
501
InitFscryptPolicy(void)502 static bool InitFscryptPolicy(void)
503 {
504 char policy[FSCRYPT_POLICY_BUF_SIZE];
505 if (LoadFscryptPolicy(policy, FSCRYPT_POLICY_BUF_SIZE) == 0) {
506 #ifndef STARTUP_INIT_TEST
507 if (SetFscryptSysparam(policy) == 0) {
508 return true;
509 }
510 #endif
511 }
512 return false;
513 }
514
DoInitGlobalKey(const struct CmdArgs * ctx)515 static void DoInitGlobalKey(const struct CmdArgs *ctx)
516 {
517 INIT_LOGV("Do init global key start");
518 const char *dataDir = "/data";
519 if (strncmp(ctx->argv[0], dataDir, strlen(dataDir)) != 0) {
520 INIT_LOGE("Not data partitation");
521 return;
522 }
523 if (!InitFscryptPolicy()) {
524 INIT_LOGW("Init fscrypt failed, not enable fscrypt");
525 return;
526 }
527
528 char * const argv[] = {
529 "/system/bin/sdc",
530 "filecrypt",
531 "init_global_key",
532 NULL
533 };
534 int argc = ARRAY_LENGTH(argv);
535 int ret = SyncExecCommand(argc, argv);
536 if (ret != 0) {
537 INIT_LOGE("[startup_failed]Init global key failed %d", INIT_GOLBALY_KEY_FAILED);
538 }
539 INIT_CMD_INFO cmdInfo;
540 cmdInfo.cmdName = "init_global_key";
541 cmdInfo.cmdContent = (const char *)&ret;
542 cmdInfo.reserved = NULL;
543 HookMgrExecute(GetBootStageHookMgr(), INIT_POST_DATA_UNENCRYPT, (void*)(&cmdInfo), NULL);
544 }
545
DoInitMainUser(const struct CmdArgs * ctx)546 static void DoInitMainUser(const struct CmdArgs *ctx)
547 {
548 char * const argv[] = {
549 "/system/bin/sdc",
550 "filecrypt",
551 "init_main_user",
552 NULL
553 };
554 int argc = ARRAY_LENGTH(argv);
555 int ret = SyncExecCommand(argc, argv);
556 INIT_CMD_INFO cmdInfo;
557 cmdInfo.cmdName = "init_main_user";
558 cmdInfo.cmdContent = (const char *)&ret;
559 cmdInfo.reserved = NULL;
560 HookMgrExecute(GetBootStageHookMgr(), INIT_POST_DATA_UNENCRYPT, (void*)(&cmdInfo), NULL);
561 }
562
DoMkswap(const struct CmdArgs * ctx)563 static void DoMkswap(const struct CmdArgs *ctx)
564 {
565 char *const argv[] = {
566 "/system/bin/mkswap",
567 ctx->argv[0],
568 NULL
569 };
570 int argc = ARRAY_LENGTH(argv);
571 SyncExecCommand(argc, argv);
572 }
573
DoSwapon(const struct CmdArgs * ctx)574 static void DoSwapon(const struct CmdArgs *ctx)
575 {
576 char *const argv[] = {
577 "/system/bin/swapon",
578 ctx->argv[0],
579 NULL
580 };
581 int argc = ARRAY_LENGTH(argv);
582 SyncExecCommand(argc, argv);
583 }
584
DoMkSandbox(const struct CmdArgs * ctx)585 static void DoMkSandbox(const struct CmdArgs *ctx)
586 {
587 INIT_LOGV("Do make sandbox start");
588 const char *sandbox = ctx->argv[0];
589 InitDefaultNamespace();
590 if (!InitSandboxWithName(sandbox)) {
591 INIT_LOGE("Failed to init sandbox with name %s.", sandbox);
592 }
593
594 if (PrepareSandbox(sandbox) != 0) {
595 INIT_LOGE("Failed to prepare sandbox %s.", sandbox);
596 DestroySandbox(sandbox);
597 }
598 if (EnterDefaultNamespace() < 0) {
599 INIT_LOGE("Failed to set default namespace.");
600 }
601 CloseDefaultNamespace();
602 }
603
DoStopFeedHighdog(const struct CmdArgs * ctx)604 static void DoStopFeedHighdog(const struct CmdArgs *ctx)
605 {
606 INIT_LOGI("stop feed highdog");
607 int fd = open("/dev/bbox", O_WRONLY);
608 if (fd < 0) {
609 INIT_LOGE("open /dev/bbox failed");
610 return;
611 }
612 int stage = SHUT_STAGE_FRAMEWORK_START;
613 int ret = ioctl(fd, SET_SHUT_STAGE, &stage);
614 if (ret < 0) {
615 INIT_LOGE("set shut stage failed");
616 }
617 close(fd);
618 return;
619 }
620
621 static const struct CmdTable g_cmdTable[] = {
622 { "syncexec ", 1, 10, 0, DoSyncExec },
623 { "exec ", 1, 10, 0, DoExec },
624 { "mknode ", 5, 5, 0, DoMakeNode },
625 { "makedev ", 2, 2, 0, DoMakeDevice },
626 { "symlink ", 2, 2, 1, DoSymlink },
627 { "trigger ", 0, 1, 0, DoTriggerCmd },
628 { "insmod ", 1, 10, 1, DoInsmod },
629 { "setparam ", 2, 2, 0, DoSetParam },
630 { "load_persist_params ", 0, 1, 0, DoLoadPersistParams },
631 { "load_private_persist_params ", 0, 1, 0, DoLoadPrivatePersistParams },
632 { "load_param ", 1, 2, 0, DoLoadDefaultParams },
633 { "load_access_token_id ", 0, 1, 0, DoLoadAccessTokenId },
634 { "ifup ", 1, 1, 1, DoIfup },
635 { "mount_fstab ", 1, 1, 0, DoMountFstabFile },
636 { "umount_fstab ", 1, 1, 0, DoUmountFstabFile },
637 { "remove_dm_device", 1, 1, 0, DoRemoveDmDevice },
638 { "mount_one_fstab", 2, 3, 0, DoMountOneFstabFile },
639 { "restorecon ", 1, 2, 1, DoRestorecon },
640 { "stopAllServices ", 0, 10, 0, DoStopAllServices },
641 { "umount ", 1, 1, 0, DoUmount },
642 { "sync ", 0, 1, 0, DoSync },
643 { "timer_start", 1, 1, 0, DoTimerStart },
644 { "timer_stop", 1, 1, 0, DoTimerStop },
645 { "init_global_key ", 1, 1, 0, DoInitGlobalKey },
646 { "init_main_user ", 0, 1, 0, DoInitMainUser },
647 { "mkswap", 1, 1, 0, DoMkswap },
648 { "swapon", 1, 1, 0, DoSwapon },
649 { "mksandbox", 1, 1, 0, DoMkSandbox },
650 { "stop_feed_highdog", 0, 1, 0, DoStopFeedHighdog },
651 { "mount_fstab_sp ", 1, 1, 0, DoMountFstabFileSp },
652 };
653
GetCmdTable(int * number)654 const struct CmdTable *GetCmdTable(int *number)
655 {
656 *number = (int)ARRAY_LENGTH(g_cmdTable);
657 return g_cmdTable;
658 }
659
OpenHidebug(const char * name)660 void OpenHidebug(const char *name)
661 {
662 #ifdef SUPPORT_PROFILER_HIDEBUG
663 InitEnvironmentParam(name);
664 #endif
665 }
666
SetFileCryptPolicy(const char * dir)667 int SetFileCryptPolicy(const char *dir)
668 {
669 if (dir == NULL) {
670 INIT_LOGE("SetFileCryptPolicy:dir is null");
671 return -EINVAL;
672 }
673 #ifndef STARTUP_INIT_TEST
674 return FscryptPolicyEnable(dir);
675 #endif
676 return 0;
677 }
678