• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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