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