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 "param_stub.h"
17#include <dirent.h>
18#include <sys/prctl.h>
19#include <unistd.h>
20
21#include "begetctl.h"
22#include "bootstage.h"
23#include "init.h"
24#include "init_log.h"
25#include "init_param.h"
26#ifndef OHOS_LITE
27#include "init_mount.h"
28#endif
29#include "hookmgr.h"
30#include "parameter.h"
31#include "param_manager.h"
32#include "param_security.h"
33#include "param_utils.h"
34#include "init_group_manager.h"
35#include "init_module_engine.h"
36#ifdef PARAM_LOAD_CFG_FROM_CODE
37#include "param_cfg.h"
38#endif
39#include "ueventd.h"
40
41#ifdef __cplusplus
42#if __cplusplus
43extern "C" {
44#endif
45#endif
46
47static int g_stubResult[STUB_MAX] = { 0 };
48static int g_testRandom = 2; // 2 is test random
49
50static int g_testPermissionResult = DAC_RESULT_PERMISSION;
51void SetTestPermissionResult(int result)
52{
53    g_testPermissionResult = result;
54}
55
56static const char *selinuxLabels[][2] = {
57    {"test.permission.read", "u:object_r:test_read:s0"},
58    {"test.permission.write", "u:object_r:test_write:s0"},
59    {"test.permission.watch", "u:object_r:test_watch:s0"},
60};
61
62static int TestGenHashCode(const char *buff)
63{
64    int code = 0;
65    size_t buffLen = strlen(buff);
66    for (size_t i = 0; i < buffLen; i++) {
67        code += buff[i] - 'A';
68    }
69    return code;
70}
71
72static void TestSetSelinuxLogCallback(void) {}
73
74static int TestSetParamCheck(const char *paraName, const char *context, const SrcInfo *info)
75{
76    BEGET_LOGI("TestSetParamCheck %s result %d", paraName, g_testPermissionResult);
77    return g_testPermissionResult;
78}
79
80static const char *TestGetParamLabel(const char *paraName)
81{
82    BEGET_LOGI("TestGetParamLabel %s", paraName);
83    if (paraName == nullptr) {
84        return nullptr;
85    }
86    for (size_t i = 0; i < ARRAY_LENGTH(selinuxLabels); i++) {
87        if (strncmp(selinuxLabels[i][0], paraName, strlen(selinuxLabels[i][0])) == 0) {
88            return selinuxLabels[i][1];
89        }
90    }
91    int code = TestGenHashCode(paraName);
92    code = code % (ARRAY_LENGTH(selinuxLabels));
93    return selinuxLabels[code][1];
94}
95
96static int32_t TestGetSelinuxLabelIndex(const char *paraName)
97{
98    for (size_t i = 0; i < ARRAY_LENGTH(selinuxLabels); i++) {
99        if (strncmp(selinuxLabels[i][0], paraName, strlen(selinuxLabels[i][0])) == 0) {
100            return i;
101        }
102    }
103    int code = TestGenHashCode(paraName);
104    code = code % (ARRAY_LENGTH(selinuxLabels));
105    return code;
106}
107
108static const char *g_forbidReadParamName[] = {
109    "ohos.servicectrl.",
110    // "test.permission.write",
111};
112static int TestReadParamCheck(const char *paraName)
113{
114    // forbid to read ohos.servicectrl.
115    for (size_t i = 0; i < ARRAY_LENGTH(g_forbidReadParamName); i++) {
116        if (strncmp(paraName, g_forbidReadParamName[i], strlen(g_forbidReadParamName[i])) == 0) {
117            return 1;
118        }
119    }
120    return g_testPermissionResult;
121}
122static void TestDestroyParamList(ParamContextsList **list)
123{
124#ifdef PARAM_SUPPORT_SELINUX
125    ParamContextsList *head = *list;
126    while (head != nullptr) {
127        ParamContextsList *next = head->next;
128        free((void *)head->info.paraName);
129        free((void *)head->info.paraContext);
130        free(head);
131        head = next;
132    }
133#endif
134}
135static ParamContextsList *TestGetParamList(void)
136{
137#ifdef PARAM_SUPPORT_SELINUX
138    ParamContextsList *head = (ParamContextsList *)malloc(sizeof(ParamContextsList));
139    BEGET_ERROR_CHECK(head != nullptr, return nullptr, "Failed to alloc ParamContextsList");
140    head->info.paraName = strdup(selinuxLabels[0][0]);
141    head->info.paraContext = strdup(selinuxLabels[0][1]);
142    head->info.index = 0;
143    head->next = nullptr;
144    for (size_t i = 1; i < ARRAY_LENGTH(selinuxLabels); i++) {
145        ParamContextsList *node = (ParamContextsList *)malloc(sizeof(ParamContextsList));
146        BEGET_ERROR_CHECK(node != nullptr, TestDestroyParamList(&head);
147            return nullptr, "Failed to alloc ParamContextsList");
148        node->info.paraName = strdup(selinuxLabels[i][0]);
149        node->info.paraContext = strdup(selinuxLabels[i][1]);
150        node->info.index = i;
151        node->next = head->next;
152        head->next = node;
153    }
154    // test error, no node paraName
155    ParamContextsList *node = (ParamContextsList *)malloc(sizeof(ParamContextsList));
156    BEGET_ERROR_CHECK(node != nullptr, TestDestroyParamList(&head);
157        return nullptr, "Failed to alloc ParamContextsList");
158    node->info.paraName = nullptr;
159    node->info.paraContext = strdup(selinuxLabels[0][1]);
160    node->next = head->next;
161    head->next = node;
162
163    // test error, no node paraContext
164    node = (ParamContextsList *)malloc(sizeof(ParamContextsList));
165    BEGET_ERROR_CHECK(node != nullptr, TestDestroyParamList(&head);
166        return nullptr, "Failed to alloc ParamContextsList");
167    node->info.paraName = strdup(selinuxLabels[0][0]);
168    node->info.paraContext = nullptr;
169    node->next = head->next;
170    head->next = node;
171
172    // test error, repeat
173    node = (ParamContextsList *)malloc(sizeof(ParamContextsList));
174    BEGET_ERROR_CHECK(node != nullptr, TestDestroyParamList(&head);
175        return nullptr, "Failed to alloc ParamContextsList");
176    node->info.paraName = strdup(selinuxLabels[0][0]);
177    node->info.paraContext = strdup(selinuxLabels[0][1]);
178    node->info.index = 0;
179    node->next = head->next;
180    head->next = node;
181    return head;
182#else
183    return nullptr;
184#endif
185}
186
187void TestSetSelinuxOps(void)
188{
189#ifdef PARAM_SUPPORT_SELINUX
190    SelinuxSpace *selinuxSpace = &GetParamWorkSpace()->selinuxSpace;
191    selinuxSpace->setSelinuxLogCallback = TestSetSelinuxLogCallback;
192    selinuxSpace->setParamCheck = TestSetParamCheck;
193    selinuxSpace->getParamLabel = TestGetParamLabel;
194    selinuxSpace->readParamCheck = TestReadParamCheck;
195    selinuxSpace->getParamList = TestGetParamList;
196    selinuxSpace->destroyParamList = TestDestroyParamList;
197    selinuxSpace->getParamLabelIndex = TestGetSelinuxLabelIndex;
198#endif
199}
200
201void TestSetParamCheckResult(const char *prefix, uint16_t mode, int result)
202{
203    ParamAuditData auditData = {};
204    auditData.name = prefix;
205    auditData.dacData.gid = 202;  // 202 test dac gid
206    auditData.dacData.uid = 202;  // 202 test dac uid
207    auditData.dacData.mode = mode;
208    AddSecurityLabel(&auditData);
209    SetTestPermissionResult(result);
210}
211
212void CreateTestFile(const char *fileName, const char *data)
213{
214    CheckAndCreateDir(fileName);
215    PARAM_LOGV("PrepareParamTestData for %s", fileName);
216    FILE *tmpFile = fopen(fileName, "wr");
217    if (tmpFile != nullptr) {
218        fprintf(tmpFile, "%s", data);
219        (void)fflush(tmpFile);
220        fclose(tmpFile);
221    }
222}
223static void PrepareUeventdcfg(void)
224{
225    const char *ueventdcfg = "[device]\n"
226        "/dev/test 0666 1000 1000\n"
227        "[device]\n"
228        "/dev/test1 0666 1000\n"
229        "[device]\n"
230        "/dev/test2 0666 1000 1000 1000 1000\n"
231        "[sysfs]\n"
232        "/dir/to/nothing attr_nowhere 0666 1000 1000\n"
233        "[sysfs]\n"
234        "  #/dir/to/nothing attr_nowhere 0666\n"
235        "[sysfs\n"
236        "/dir/to/nothing attr_nowhere 0666\n"
237        "[firmware]\n"
238        "/etc\n"
239        "[device]\n"
240        "/dev/testbinder 0666 1000 1000 const.dev.binder\n"
241        "[device]\n"
242        "/dev/testbinder1 0666 1000 1000 const.dev.binder\n"
243        "[device]\n"
244        "/dev/testbinder2 0666 1000 1000 const.dev.binder\n"
245        "[device]\n"
246        "/dev/testbinder3 0666 1000 1000 const.dev.binder\n";
247    mkdir("/data/ueventd_ut", S_IRWXU | S_IRWXG | S_IRWXO);
248    CreateTestFile(STARTUP_INIT_UT_PATH"/ueventd_ut/valid.config", ueventdcfg);
249}
250static void PrepareModCfg(void)
251{
252    const char *modCfg = "testinsmod";
253    CreateTestFile(STARTUP_INIT_UT_PATH"/test_insmod", modCfg);
254}
255static void PrepareInnerKitsCfg()
256{
257    const char *innerKitsCfg = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/system /system "
258        "ext4 ro,barrier=1 wait\n"
259        "/dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor "
260        "ext4 ro,barrier=1 wait\n"
261        "/dev/block/platform/soc/10100000.himci.eMMC/by-name/hos "
262        "/hos ntfs nosuid,nodev,noatime,barrier=1,data=ordered wait\n"
263        "/dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data ext4 "
264        "nosuid,nodev,noatime,barrier=1,data=ordered,noauto_da_alloc "
265        "wait,reservedsize=104857600\n"
266        "  aaaa\n"
267        "aa aa\n"
268        "aa aa aa\n"
269        "aa aa aa aa\n";
270    const char *fstabRequired = "# fstab file.\n"
271        "#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>\n"
272        "/dev/block/platform/fe310000.sdhci/by-name/testsystem /usr ext4 ro,barrier=1 wait,required,nofail\n"
273        "/dev/block/platform/fe310000.sdhci/by-name/testvendor /vendor ext4 ro,barrier=1 wait,required\n"
274        "/dev/block/platform/fe310000.sdhci/by-name/testuserdata1 /data f2fs noatime,nosuid,nodev wait,check,quota\n"
275        "/dev/block/platform/fe310000.sdhci/by-name/testuserdata2 /data ext4 noatime,fscrypt=xxx wait,check,quota\n"
276        "/dev/block/platform/fe310000.sdhci/by-name/testmisc /misc none none wait,required";
277    mkdir("/data/init_ut/mount_unitest/", S_IRWXU | S_IRWXG | S_IRWXO);
278    CreateTestFile(STARTUP_INIT_UT_PATH"/mount_unitest/ReadFstabFromFile1.fstable", innerKitsCfg);
279    CreateTestFile(STARTUP_INIT_UT_PATH"/etc/fstab.required", fstabRequired);
280    CreateTestFile(STARTUP_INIT_UT_PATH"/system/etc/fstab.required", fstabRequired);
281}
282static void PrepareGroupTestCfg()
283{
284    const char *data = "{"
285	    "\"jobs\": [\"param:job1\", \"param:job2\", \"param:job4\"],"
286	    "\"services\": [\"service:service1\", \"service:service3\", \"service:service2\"],"
287	    "\"groups\": [\"subsystem.xxx1.group\", \"subsystem.xxx2.group\", \"subsystem.xxx4.group\"]"
288    "}";
289    const char *xxx1 = "{"
290	    "\"groups\": [\"subsystem.xxx11.group\""
291    "}";
292    const char *xxx11 = "{"
293	    "\"groups\": [\"subsystem.xxx12.group\""
294    "}";
295    const char *xxx12 = "{"
296	    "\"groups\": [\"subsystem.xxx13.group\""
297    "}";
298    const char *xxx13 = "{"
299	    "\"groups\": [\"subsystem.xxx14.group\""
300    "}";
301    const char *xxx14 = "{"
302	    "\"groups\": [\"subsystem.xxx11.group\""
303    "}";
304    CreateTestFile(GROUP_DEFAULT_PATH "/device.boot.group.cfg", data);
305    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx1.group.cfg", xxx1);
306    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx11.group.cfg", xxx11);
307    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx12.group.cfg", xxx12);
308    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx13.group.cfg", xxx13);
309    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx14.group.cfg", xxx14);
310}
311static bool IsDir(const std::string &path)
312{
313    struct stat st {};
314    if (stat(path.c_str(), &st) < 0) {
315        return false;
316    }
317    return S_ISDIR(st.st_mode);
318}
319static bool DeleteDir(const std::string &path)
320{
321    auto pDir = std::unique_ptr<DIR, decltype(&closedir)>(opendir(path.c_str()), closedir);
322    if (pDir == nullptr) {
323        return false;
324    }
325
326    struct dirent *dp = nullptr;
327    while ((dp = readdir(pDir.get())) != nullptr) {
328        std::string currentName(dp->d_name);
329        if (currentName[0] != '.') {
330            std::string tmpName(path);
331            tmpName.append("/" + currentName);
332            if (IsDir(tmpName)) {
333                DeleteDir(tmpName);
334            }
335            remove(tmpName.c_str());
336        }
337    }
338    if (remove(path.c_str()) != 0) {
339        return false;
340    }
341    return true;
342}
343static void LoadParamFromCfg(void)
344{
345#ifdef PARAM_LOAD_CFG_FROM_CODE
346    for (size_t i = 0; i < ARRAY_LENGTH(g_paramDefCfgNodes); i++) {
347        PARAM_LOGI("InitParamClient name %s = %s", g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value);
348        uint32_t dataIndex = 0;
349        int ret = WriteParam(g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value, &dataIndex, 0);
350        PARAM_CHECK(ret == 0, continue, "Failed to set param %d name %s %s",
351            ret, g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value);
352    }
353#endif
354}
355
356static const char *g_triggerData = "{"
357        "\"jobs\" : [{"
358        "        \"name\" : \"early-init\","
359        "        \"cmds\" : ["
360        "            \"    write        '/proc/sys/kernel/sysrq 0'\","
361        "            \"    load_persist_params \","
362        "            \"    load_persist_params        \","
363        "            \" #   load_persist_params \","
364        "            \"   restorecon /postinstall\","
365        "            \"mkdir /acct/uid\","
366        "            \"chown root system /dev/memcg/memory.pressure_level\","
367        "            \"chmod 0040 /dev/memcg/memory.pressure_level\","
368        "            \"mkdir /dev/memcg/apps/ 0755 system system\","
369        "           \"mkdir /dev/memcg/system 0550 system system\","
370        "            \"start ueventd\","
371        "            \"exec_start apexd-bootstrap\","
372        "            \"setparam sys.usb.config ${persist.sys.usb.config}\""
373        "        ]"
374        "    },"
375        "    {"
376        "        \"name\" : \"param:trigger_test_1\","
377        "        \"condition\" : \"test.sys.boot_from_charger_mode=5\","
378        "        \"cmds\" : ["
379        "            \"class_stop charger\","
380        "            \"trigger late-init\""
381        "        ]"
382        "    },"
383        "    {"
384        "        \"name\" : \"param:trigger_test_2\","
385        "        \"condition\" : \"test.sys.boot_from_charger_mode=1  "
386        " || test.sys.boot_from_charger_mode=2   ||  test.sys.boot_from_charger_mode=3\","
387        "        \"cmds\" : ["
388        "            \"class_stop charger\","
389        "            \"trigger late-init\""
390        "        ]"
391        "    },"
392        "    {"
393        "        \"name\" : \"load_persist_params_action\","
394        "        \"cmds\" : ["
395        "           \"load_persist_params\","
396        "            \"start logd\","
397        "            \"start logd-reinit\""
398        "        ]"
399        "    },"
400        "    {"
401        "        \"name\" : \"firmware_mounts_complete\","
402        "        \"cmds\" : ["
403        "            \"rm /dev/.booting\""
404        "        ]"
405        "    }"
406        "]"
407    "}";
408
409void PrepareCmdLineData()
410{
411    const char *cmdLine = "bootgroup=device.boot.group earlycon=uart8250,mmio32,0xfe660000 "
412        "root=PARTUUID=614e0000-0000 rw rootwait rootfstype=ext4 console=ttyFIQ0 hardware=rk3568 "
413        "BOOT_IMAGE=/kernel init=/init default_boot_device=fe310000.sdhci bootslots=2 currentslot=1 initloglevel=2 "
414        "ohos.required_mount.system="
415        "/dev/block/platform/fe310000.sdhci/by-name/system@/usr@ext4@ro,barrier=1@wait,required "
416        "ohos.required_mount.vendor="
417        "/dev/block/platform/fe310000.sdhci/by-name/vendor@/vendor@ext4@ro,barrier=1@wait,required "
418        "ohos.required_mount.misc="
419        "/dev/block/platform/fe310000.sdhci/by-name/misc@none@none@none@wait,required ohos.boot.eng_mode=on ";
420    CreateTestFile(BOOT_CMD_LINE, cmdLine);
421}
422
423static void PrepareAreaSizeFile(void)
424{
425    const char *ohosParamSize = "default_param=1024\n"
426            "hilog_param=2048\n"
427            "const_product_param=2048\n"
428            "startup_param=20480\n"
429            "persist_param=2048\n"
430            "const_param=20480\n"
431            "test_watch=102400\n"
432            "test_write=102400\n"
433            "const_param***=20480\n"
434            "persist_sys_param=2048\n"
435            "test_write=102400\n";
436    CreateTestFile(PARAM_AREA_SIZE_CFG, ohosParamSize);
437}
438
439static void PrepareTestGroupFile(void)
440{
441    std::string groupData = "root:x:0:\n"
442        "bin:x:2:\n"
443        "system:x:1000:\n"
444        "log:x:1007:\n"
445        "deviceinfo:x:1102:\n"
446        "samgr:x:5555:\n"
447        "hdf_devmgr:x:3044:\n\n"
448        "power_host:x:3025:\n"
449        "servicectrl:x:1050:root,  shell,system,   samgr,   hdf_devmgr      \n"
450        "powerctrl:x:1051:root, shell,system,  update,power_host\r\n"
451        "bootctrl:x:1052:root,shell,system\n"
452        "deviceprivate:x:1053:root,shell,system,samgr,hdf_devmgr,deviceinfo,"
453        "dsoftbus,dms,account,useriam,access_token,device_manager,foundation,dbms,deviceauth,huks_server\n"
454        "hiview:x:1201:\n"
455        "hidumper_service:x:1212:\n"
456        "shell:x:2000:\n"
457        "cache:x:2001:\n"
458        "net_bw_stats:x:3006:\n";
459
460    CreateTestFile(STARTUP_INIT_UT_PATH "/etc/group", groupData.c_str());
461}
462
463static void PrepareDacData()
464{
465    // for dac
466    std::string dacData = "ohos.servicectrl.   = system:servicectrl:0775 \n";
467    dacData += "startup.service.ctl.        = system:servicectrl:0775:int\n";
468    dacData += "test.permission.       = root:root:0770\n";
469    dacData += "test.permission.read. =  root:root:0774\n";
470    dacData += "test.permission.write.=  root:root:0772\n";
471    dacData += "test.permission.watcher. = root:root:0771\n";
472    dacData += "test.test1. = system:test1:0771\n";
473    dacData += "test.test2.watcher. = test2:root:0771\n";
474    dacData += "test.type.int. = root:root:0777:int\n";
475    dacData += "test.type.bool. = root:root:0777:bool\n";
476    dacData += "test.type.string. = root:root:0777\n";
477    dacData += "test.invalid.int. = root:root:\n";
478    dacData += "test.invalid.int. = root::\n";
479    dacData += "test.invalid.int. = ::\n";
480    dacData += "test.invalid.int. = \n";
481    dacData += "test.invalid.int. \n";
482    CreateTestFile(STARTUP_INIT_UT_PATH "/system/etc/param/ohos.para.dac", dacData.c_str());
483    CreateTestFile(STARTUP_INIT_UT_PATH "/system/etc/param/ohos.para.dac_1", dacData.c_str());
484}
485
486static int TestHook(const HOOK_INFO *hookInfo, void *cookie)
487{
488    return 0;
489}
490
491void PrepareInitUnitTestEnv(void)
492{
493    static int evnOk = 0;
494    if (evnOk) {
495        return;
496    }
497    printf("PrepareInitUnitTestEnv \n");
498#ifdef PARAM_SUPPORT_SELINUX
499    RegisterSecuritySelinuxOps(nullptr, 0);
500#endif
501
502#ifndef OHOS_LITE
503    InitAddGlobalInitHook(0, TestHook);
504    InitAddPreParamServiceHook(0, TestHook);
505    InitAddPreParamLoadHook(0, TestHook);
506    InitAddPreCfgLoadHook(0, TestHook);
507    InitAddPostCfgLoadHook(0, TestHook);
508    InitAddPostPersistParamLoadHook(0, TestHook);
509#endif
510    // read default parameter from system
511    LoadDefaultParams("/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
512    LoadDefaultParams("/vendor/etc/param", LOAD_PARAM_NORMAL);
513    LoadDefaultParams("/system/etc/param", LOAD_PARAM_ONLY_ADD);
514
515    // read ut parameters
516    LoadDefaultParams(STARTUP_INIT_UT_PATH "/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
517    LoadDefaultParams(STARTUP_INIT_UT_PATH "/vendor/etc/param", LOAD_PARAM_NORMAL);
518    LoadDefaultParams(STARTUP_INIT_UT_PATH "/system/etc/param", LOAD_PARAM_ONLY_ADD);
519    LoadParamsFile(STARTUP_INIT_UT_PATH "/system/etc/param", LOAD_PARAM_ONLY_ADD);
520    LoadParamFromCfg();
521
522    int32_t loglevel = GetIntParameter("persist.init.debug.loglevel", INIT_ERROR);
523    SetInitLogLevel((InitLogLevel)loglevel);
524
525    // for test int get
526    SystemWriteParam("test.int.get", "-101");
527    SystemWriteParam("test.uint.get", "101");
528    SystemWriteParam("test.string.get", "101");
529    SystemWriteParam("test.bool.get.true", "true");
530    SystemWriteParam("test.bool.get.false", "false");
531
532    evnOk = 1;
533}
534
535int TestCheckParamPermission(const ParamLabelIndex *labelIndex,
536    const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
537{
538    // DAC_RESULT_FORBIDED
539    return g_testPermissionResult;
540}
541
542int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel)
543{
544    return 0;
545}
546
547void SetStubResult(STUB_TYPE type, int result)
548{
549    g_stubResult[type] = result;
550}
551
552#ifndef OHOS_LITE
553static void TestBeforeInit(void)
554{
555    ParamWorkSpace *paramSpace = GetParamWorkSpace();
556    EXPECT_NE(paramSpace, nullptr);
557    InitParamService();
558    CloseParamWorkSpace();
559    paramSpace = GetParamWorkSpace();
560    EXPECT_NE(paramSpace, nullptr);
561
562    // test read cmdline
563    Fstab *stab = LoadRequiredFstab();
564    ReleaseFstab(stab);
565}
566#endif
567
568static pid_t g_currPid = 0;
569static __attribute__((constructor(101))) void ParamTestStubInit(void)
570{
571    g_currPid = getpid();
572    printf("Init unit test start %u \n", g_currPid);
573    EnableInitLog(INIT_INFO);
574    InitParseGroupCfg();
575    // prepare data
576    mkdir(STARTUP_INIT_UT_PATH, S_IRWXU | S_IRWXG | S_IRWXO);
577    CheckAndCreateDir(STARTUP_INIT_UT_PATH MODULE_LIB_NAME "/autorun/");
578    int cmdIndex = 0;
579    (void)GetMatchCmd("copy ", &cmdIndex);
580    DoCmdByIndex(cmdIndex, MODULE_LIB_NAME"/libbootchart.z.so "
581        STARTUP_INIT_UT_PATH MODULE_LIB_NAME "/libbootchart.z.so", nullptr);
582    DoCmdByIndex(cmdIndex, MODULE_LIB_NAME"/libbootchart.z.so "
583        STARTUP_INIT_UT_PATH MODULE_LIB_NAME "/autorun/libbootchart.z.so", nullptr);
584    PrepareUeventdcfg();
585    PrepareInnerKitsCfg();
586    PrepareModCfg();
587    PrepareGroupTestCfg();
588    PrepareDacData();
589    CreateTestFile(STARTUP_INIT_UT_PATH"/trigger_test.cfg", g_triggerData);
590    PrepareAreaSizeFile();
591    PrepareTestGroupFile();
592    PrepareCmdLineData();
593    TestSetSelinuxOps();
594
595    PARAM_LOGI("TestSetSelinuxOps \n");
596#ifndef OHOS_LITE
597    TestBeforeInit();
598#endif
599#ifndef __LITEOS_A__
600    SystemInit();
601#endif
602    PARAM_LOGI("SystemConfig \n");
603    SystemConfig(NULL);
604    PrepareInitUnitTestEnv();
605}
606
607__attribute__((destructor)) static void ParamTestStubExit(void)
608{
609    PARAM_LOGI("ParamTestStubExit %u %u \n", g_currPid, getpid());
610    if (g_currPid != getpid()) {
611        return;
612    }
613#ifndef OHOS_LITE
614    StopParamService();
615
616    HookMgrExecute(GetBootStageHookMgr(), INIT_BOOT_COMPLETE, nullptr, nullptr);
617    CloseUeventConfig();
618    CloseServiceSpace();
619    demoExit();
620    LE_CloseLoop(LE_GetDefaultLoop());
621    HookMgrDestroy(GetBootStageHookMgr());
622#endif
623}
624
625#ifdef OHOS_LITE
626void __attribute__((weak))LE_DoAsyncEvent(const LoopHandle loopHandle, const TaskHandle taskHandle)
627{
628}
629
630const char* HalGetSerial(void)
631{
632    static const char *serial = "1234567890";
633    return serial;
634}
635#endif
636
637int __attribute__((weak))SprintfStub(char *buffer, size_t size, const char *fmt, ...)
638{
639    int len = -1;
640    va_list vargs;
641    va_start(vargs, fmt);
642    len = vsnprintf_s(buffer, size, size - 1, fmt, vargs);
643    va_end(vargs);
644    return len;
645}
646
647int __attribute__((weak))MountStub(const char* source, const char* target,
648    const char* filesystemtype, unsigned long mountflags, const void * data)
649{
650    return g_stubResult[STUB_MOUNT];
651}
652
653int __attribute__((weak))UmountStub(const char *target)
654{
655    return 0;
656}
657
658int __attribute__((weak))Umount2Stub(const char *target, int flags)
659{
660    return 0;
661}
662
663int __attribute__((weak))SymlinkStub(const char * oldpath, const char * newpath)
664{
665    return 0;
666}
667
668int PrctlStub(int option, ...)
669{
670    if (option == PR_SET_SECUREBITS) {
671        static int count = 0;
672        count++;
673        return (count % g_testRandom == 1) ? 0 : -1;
674    }
675    if (option == PR_CAP_AMBIENT) {
676        static int count1 = 0;
677        count1++;
678        return (count1 % g_testRandom == 1) ? 0 : -1;
679    }
680    return 0;
681}
682
683int ExecvStub(const char *pathname, char *const argv[])
684{
685    printf("ExecvStub %s \n", pathname);
686    return 0;
687}
688
689int LchownStub(const char *pathname, uid_t owner, gid_t group)
690{
691    return 0;
692}
693
694int KillStub(pid_t pid, int signal)
695{
696    return 0;
697}
698
699int ExecveStub(const char *pathname, char *const argv[], char *const envp[])
700{
701    printf("ExecveStub %s \n", pathname);
702    return 0;
703}
704
705int LoadPolicy()
706{
707    return 0;
708}
709
710static int g_selinuxOptResult = 0;
711int setcon(const char *name)
712{
713    g_selinuxOptResult++;
714    return g_selinuxOptResult % g_testRandom;
715}
716
717int RestoreconRecurse(const char *name)
718{
719    g_selinuxOptResult++;
720    return g_selinuxOptResult % g_testRandom;
721}
722
723int setexeccon(const char *name)
724{
725    g_selinuxOptResult++;
726    return g_selinuxOptResult % g_testRandom;
727}
728
729int setsockcreatecon(const char *name)
730{
731    g_selinuxOptResult++;
732    return g_selinuxOptResult % g_testRandom;
733}
734
735int setfilecon(const char *name, const char *content)
736{
737    g_selinuxOptResult++;
738    return g_selinuxOptResult % g_testRandom;
739}
740
741ParamLabelIndex *TestGetParamLabelIndex(const char *name)
742{
743    static ParamLabelIndex labelIndex = {0};
744    uint32_t index = 0;
745    ParamWorkSpace *paramWorkspace = GetParamWorkSpace();
746    if (paramWorkspace == nullptr) {
747        return &labelIndex;
748    }
749#ifdef PARAM_SUPPORT_SELINUX
750    if (paramWorkspace->selinuxSpace.getParamLabelIndex == nullptr) {
751        return &labelIndex;
752    }
753    index = (uint32_t)paramWorkspace->selinuxSpace.getParamLabelIndex(name) + WORKSPACE_INDEX_BASE;
754    if (index >= paramWorkspace->maxLabelIndex) {
755        return &labelIndex;
756    }
757#endif
758    labelIndex.workspace = paramWorkspace->workSpace[index];
759    PARAM_CHECK(labelIndex.workspace != nullptr, return nullptr, "Invalid workSpace");
760    labelIndex.selinuxLabelIndex = labelIndex.workspace->spaceIndex;
761    (void)FindTrieNode(paramWorkspace->workSpace[0], name, strlen(name), &labelIndex.dacLabelIndex);
762    return &labelIndex;
763}
764#ifdef __cplusplus
765#if __cplusplus
766}
767#endif
768#endif
769