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 "init_log.h"
19 #include "init_param.h"
20 #include "param_manager.h"
21 #include "param_security.h"
22 #include "param_utils.h"
23 #include "init_group_manager.h"
24 #include "init_module_engine.h"
25 #include "beget_ext.h"
26 #ifdef PARAM_LOAD_CFG_FROM_CODE
27 #include "param_cfg.h"
28 #endif
29
30 #ifdef __cplusplus
31 #if __cplusplus
32 extern "C" {
33 #endif
34 #endif
35 int LoadParamFromCmdLine(void);
36 static int g_testPermissionResult = DAC_RESULT_PERMISSION;
SetTestPermissionResult(int result)37 void SetTestPermissionResult(int result)
38 {
39 g_testPermissionResult = result;
40 }
41
42 static const char *selinuxLabels[][2] = {
43 {"test.permission.read", "test.persmission.read"},
44 {"test.permission.write", "test.persmission.write"},
45 {"test.permission.watch", "test.persmission.watch"}
46 };
47
TestGenHashCode(const char * buff)48 static int TestGenHashCode(const char *buff)
49 {
50 int code = 0;
51 size_t buffLen = strlen(buff);
52 for (size_t i = 0; i < buffLen; i++) {
53 code += buff[i] - 'A';
54 }
55 return code;
56 }
57
TestSetSelinuxLogCallback(void)58 static void TestSetSelinuxLogCallback(void) {}
59
TestSetParamCheck(const char * paraName,const char * context,const SrcInfo * info)60 static int TestSetParamCheck(const char *paraName, const char *context, const SrcInfo *info)
61 {
62 BEGET_LOGI("TestSetParamCheck %s result %d", paraName, g_testPermissionResult);
63 return g_testPermissionResult;
64 }
65
TestGetParamLabel(const char * paraName)66 static const char *TestGetParamLabel(const char *paraName)
67 {
68 BEGET_LOGI("TestGetParamLabel %s", paraName);
69 for (size_t i = 0; i < ARRAY_LENGTH(selinuxLabels); i++) {
70 if (strncmp(selinuxLabels[i][0], paraName, strlen(selinuxLabels[i][0])) == 0) {
71 return selinuxLabels[i][1];
72 }
73 }
74 int code = TestGenHashCode(paraName);
75 code = code % (ARRAY_LENGTH(selinuxLabels));
76 return selinuxLabels[code][1];
77 }
78
79 static const char *g_forbidReadParamName[] = {
80 "ohos.servicectrl.",
81 // "test.permission.write",
82 };
TestReadParamCheck(const char * paraName)83 static int TestReadParamCheck(const char *paraName)
84 {
85 // forbid to read ohos.servicectrl.
86 for (size_t i = 0; i < ARRAY_LENGTH(g_forbidReadParamName); i++) {
87 if (strncmp(paraName, g_forbidReadParamName[i], strlen(g_forbidReadParamName[i])) == 0) {
88 return 1;
89 }
90 }
91 return g_testPermissionResult;
92 }
TestDestroyParamList(ParamContextsList ** list)93 static void TestDestroyParamList(ParamContextsList **list)
94 {
95 #ifdef PARAM_SUPPORT_SELINUX
96 ParamContextsList *head = *list;
97 while (head != nullptr) {
98 ParamContextsList *next = head->next;
99 free((void *)head->info.paraName);
100 free((void *)head->info.paraContext);
101 free(head);
102 head = next;
103 }
104 #endif
105 }
TestGetParamList(void)106 static ParamContextsList *TestGetParamList(void)
107 {
108 #ifdef PARAM_SUPPORT_SELINUX
109 ParamContextsList *head = (ParamContextsList *)malloc(sizeof(ParamContextsList));
110 BEGET_ERROR_CHECK(head != nullptr, return nullptr, "Failed to alloc ParamContextsList");
111 head->info.paraName = strdup(selinuxLabels[0][0]);
112 head->info.paraContext = strdup(selinuxLabels[0][1]);
113 head->next = nullptr;
114 for (size_t i = 1; i < ARRAY_LENGTH(selinuxLabels); i++) {
115 ParamContextsList *node = (ParamContextsList *)malloc(sizeof(ParamContextsList));
116 BEGET_ERROR_CHECK(node != nullptr, TestDestroyParamList(&head);
117 return nullptr, "Failed to alloc ParamContextsList");
118 node->info.paraName = strdup(selinuxLabels[i][0]);
119 node->info.paraContext = strdup(selinuxLabels[i][1]);
120 node->next = head->next;
121 head->next = node;
122 }
123 return head;
124 #else
125 return nullptr;
126 #endif
127 }
128
TestSetSelinuxOps(void)129 void TestSetSelinuxOps(void)
130 {
131 #ifdef PARAM_SUPPORT_SELINUX
132 SelinuxSpace *selinuxSpace = &GetParamWorkSpace()->selinuxSpace;
133 selinuxSpace->setSelinuxLogCallback = TestSetSelinuxLogCallback;
134 selinuxSpace->setParamCheck = TestSetParamCheck;
135 selinuxSpace->getParamLabel = TestGetParamLabel;
136 selinuxSpace->readParamCheck = TestReadParamCheck;
137 selinuxSpace->getParamList = TestGetParamList;
138 selinuxSpace->destroyParamList = TestDestroyParamList;
139 #endif
140 }
141
TestSetParamCheckResult(const char * prefix,uint16_t mode,int result)142 void TestSetParamCheckResult(const char *prefix, uint16_t mode, int result)
143 {
144 ParamAuditData auditData = {};
145 auditData.name = prefix;
146 auditData.dacData.gid = 202; // 202 test dac gid
147 auditData.dacData.uid = 202; // 202 test dac uid
148 auditData.dacData.mode = mode;
149 AddSecurityLabel(&auditData);
150 SetTestPermissionResult(result);
151 }
152
CreateTestFile(const char * fileName,const char * data)153 static void CreateTestFile(const char *fileName, const char *data)
154 {
155 CheckAndCreateDir(fileName);
156 PARAM_LOGV("PrepareParamTestData for %s", fileName);
157 FILE *tmpFile = fopen(fileName, "wr");
158 if (tmpFile != nullptr) {
159 fprintf(tmpFile, "%s", data);
160 (void)fflush(tmpFile);
161 fclose(tmpFile);
162 }
163 }
PrepareUeventdcfg(void)164 static void PrepareUeventdcfg(void)
165 {
166 const char *ueventdcfg = "[device]\n"
167 "/dev/test 0666 1000 1000\n"
168 "[device]\n"
169 "/dev/test1 0666 1000\n"
170 "[device]\n"
171 "/dev/test2 0666 1000 1000 1000 1000\n"
172 "[sysfs]\n"
173 "/dir/to/nothing attr_nowhere 0666 1000 1000\n"
174 "[sysfs]\n"
175 " #/dir/to/nothing attr_nowhere 0666\n"
176 "[sysfs\n"
177 "/dir/to/nothing attr_nowhere 0666\n"
178 "[firmware]\n"
179 "/etc\n"
180 "[device]\n"
181 "/dev/testbinder 0666 1000 1000 const.dev.binder\n"
182 "[device]\n"
183 "/dev/testbinder1 0666 1000 1000 const.dev.binder\n"
184 "[device]\n"
185 "/dev/testbinder2 0666 1000 1000 const.dev.binder\n"
186 "[device]\n"
187 "/dev/testbinder3 0666 1000 1000 const.dev.binder\n";
188 mkdir("/data/ueventd_ut", S_IRWXU | S_IRWXG | S_IRWXO);
189 CreateTestFile(STARTUP_INIT_UT_PATH"/ueventd_ut/valid.config", ueventdcfg);
190 }
PrepareModCfg(void)191 static void PrepareModCfg(void)
192 {
193 const char *modCfg = "testinsmod";
194 CreateTestFile("/data/init_ut/test_insmod", modCfg);
195 }
PrepareInnerKitsCfg()196 static void PrepareInnerKitsCfg()
197 {
198 const char *innerKitsCfg = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/system /system "
199 "ext4 ro,barrier=1 wait\n"
200 "/dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor "
201 "ext4 ro,barrier=1 wait\n"
202 "/dev/block/platform/soc/10100000.himci.eMMC/by-name/hos "
203 "/hos ntfs nosuid,nodev,noatime,barrier=1,data=ordered wait\n"
204 "/dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data ext4 "
205 "nosuid,nodev,noatime,barrier=1,data=ordered,noauto_da_alloc "
206 "wait,reservedsize=104857600\n"
207 " aaaa\n"
208 "aa aa\n"
209 "aa aa aa\n"
210 "aa aa aa aa\n";
211 const char *fstabRequired = "# fstab file.\n"
212 "#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>\n"
213 "/dev/block/platform/fe310000.sdhci/by-name/testsystem /usr ext4 ro,barrier=1 wait,required,nofail\n"
214 "/dev/block/platform/fe310000.sdhci/by-name/testvendor /vendor ext4 ro,barrier=1 wait,required\n"
215 "/dev/block/platform/fe310000.sdhci/by-name/testuserdata1 /data f2fs noatime,nosuid,nodev wait,check,quota\n"
216 "/dev/block/platform/fe310000.sdhci/by-name/testuserdata2 /data ext4 noatime,fscrypt=xxx wait,check,quota\n"
217 "/dev/block/platform/fe310000.sdhci/by-name/testmisc /misc none none wait,required";
218 mkdir("/data/init_ut/mount_unitest/", S_IRWXU | S_IRWXG | S_IRWXO);
219 CreateTestFile("/data/init_ut/mount_unitest/ReadFstabFromFile1.fstable", innerKitsCfg);
220 CreateTestFile("/data/init_ut/etc/fstab.required", fstabRequired);
221 }
PrepareGroupTestCfg()222 static void PrepareGroupTestCfg()
223 {
224 const char *data = "{"
225 "\"jobs\": [\"param:job1\", \"param:job2\", \"param:job4\"],"
226 "\"services\": [\"service:service1\", \"service:service3\", \"service:service2\"],"
227 "\"groups\": [\"subsystem.xxx1.group\", \"subsystem.xxx2.group\", \"subsystem.xxx4.group\"]"
228 "}";
229 const char *xxx1 = "{"
230 "\"groups\": [\"subsystem.xxx11.group\""
231 "}";
232 const char *xxx11 = "{"
233 "\"groups\": [\"subsystem.xxx12.group\""
234 "}";
235 const char *xxx12 = "{"
236 "\"groups\": [\"subsystem.xxx13.group\""
237 "}";
238 const char *xxx13 = "{"
239 "\"groups\": [\"subsystem.xxx14.group\""
240 "}";
241 const char *xxx14 = "{"
242 "\"groups\": [\"subsystem.xxx11.group\""
243 "}";
244 CreateTestFile(GROUP_DEFAULT_PATH "/device.boot.group.cfg", data);
245 CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx1.group.cfg", xxx1);
246 CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx11.group.cfg", xxx11);
247 CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx12.group.cfg", xxx12);
248 CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx13.group.cfg", xxx13);
249 CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx14.group.cfg", xxx14);
250 }
IsDir(const std::string & path)251 static bool IsDir(const std::string &path)
252 {
253 struct stat st {};
254 if (stat(path.c_str(), &st) < 0) {
255 return false;
256 }
257 return S_ISDIR(st.st_mode);
258 }
DeleteDir(const std::string & path)259 static bool DeleteDir(const std::string &path)
260 {
261 auto pDir = std::unique_ptr<DIR, decltype(&closedir)>(opendir(path.c_str()), closedir);
262 if (pDir == nullptr) {
263 return false;
264 }
265
266 struct dirent *dp = nullptr;
267 while ((dp = readdir(pDir.get())) != nullptr) {
268 std::string currentName(dp->d_name);
269 if (currentName[0] != '.') {
270 std::string tmpName(path);
271 tmpName.append("/" + currentName);
272 if (IsDir(tmpName)) {
273 DeleteDir(tmpName);
274 }
275 remove(tmpName.c_str());
276 }
277 }
278 if (remove(path.c_str()) != 0) {
279 return false;
280 }
281 return true;
282 }
LoadParamFromCfg(void)283 static void LoadParamFromCfg(void)
284 {
285 #ifdef PARAM_LOAD_CFG_FROM_CODE
286 for (size_t i = 0; i < ARRAY_LENGTH(g_paramDefCfgNodes); i++) {
287 PARAM_LOGI("InitParamClient name %s = %s", g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value);
288 uint32_t dataIndex = 0;
289 int ret = WriteParam(g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value, &dataIndex, 0);
290 PARAM_CHECK(ret == 0, continue, "Failed to set param %d name %s %s",
291 ret, g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value);
292 }
293 #endif
294 }
295 #if !(defined __LITEOS_A__ || defined __LITEOS_M__)
296 static const char *g_triggerData = "{"
297 "\"jobs\" : [{"
298 " \"name\" : \"early-init\","
299 " \"cmds\" : ["
300 " \" write '/proc/sys/kernel/sysrq 0'\","
301 " \" load_persist_params \","
302 " \" load_persist_params \","
303 " \" # load_persist_params \","
304 " \" restorecon /postinstall\","
305 " \"mkdir /acct/uid\","
306 " \"chown root system /dev/memcg/memory.pressure_level\","
307 " \"chmod 0040 /dev/memcg/memory.pressure_level\","
308 " \"mkdir /dev/memcg/apps/ 0755 system system\","
309 " \"mkdir /dev/memcg/system 0550 system system\","
310 " \"start ueventd\","
311 " \"exec_start apexd-bootstrap\","
312 " \"setparam sys.usb.config ${persist.sys.usb.config}\""
313 " ]"
314 " },"
315 " {"
316 " \"name\" : \"param:trigger_test_1\","
317 " \"condition\" : \"test.sys.boot_from_charger_mode=5\","
318 " \"cmds\" : ["
319 " \"class_stop charger\","
320 " \"trigger late-init\""
321 " ]"
322 " },"
323 " {"
324 " \"name\" : \"param:trigger_test_2\","
325 " \"condition\" : \"test.sys.boot_from_charger_mode=1 "
326 " || test.sys.boot_from_charger_mode=2 || test.sys.boot_from_charger_mode=3\","
327 " \"cmds\" : ["
328 " \"class_stop charger\","
329 " \"trigger late-init\""
330 " ]"
331 " },"
332 " {"
333 " \"name\" : \"load_persist_params_action\","
334 " \"cmds\" : ["
335 " \"load_persist_params\","
336 " \"start logd\","
337 " \"start logd-reinit\""
338 " ]"
339 " },"
340 " {"
341 " \"name\" : \"firmware_mounts_complete\","
342 " \"cmds\" : ["
343 " \"rm /dev/.booting\""
344 " ]"
345 " }"
346 "]"
347 "}";
348 #endif
349
PrepareCmdLineHasSn()350 void PrepareCmdLineHasSn()
351 {
352 // for cmdline
353 const char *cmdLineHasSnroot = "bootgroup=device.charge.group earlycon=uart8250,mmio32,0xfe660000 "
354 "root=PARTUUID=614e0000-0000 rw rootwait rootfstype=ext4 console=ttyFIQ0 hardware=rk3568"
355 " BOOT_IMAGE=/kernel ohos.boot.sn=/test init=/init";
356 CreateTestFile(BOOT_CMD_LINE, cmdLineHasSnroot);
357 LoadParamFromCmdLine();
358 const char *cmdLineHasntSn = "bootgroup=device.charge.group earlycon=uart8250,mmio32,0xfe660000 "
359 "root=PARTUUID=614e0000-0000 rw rootwait rootfstype=ext4 console=ttyFIQ0 hardware=rk3568 "
360 "BOOT_IMAGE=/kernel init=/init default_boot_device=fe310000.sdhci bootslots=2 currentslot=1 "
361 "ohos.required_mount.system="
362 "/dev/block/platform/fe310000.sdhci/by-name/system@/usr@ext4@ro,barrier=1@wait,required "
363 "ohos.required_mount.vendor="
364 "/dev/block/platform/fe310000.sdhci/by-name/vendor@/vendor@ext4@ro,barrier=1@wait,required "
365 "ohos.required_mount.misc="
366 "/dev/block/platform/fe310000.sdhci/by-name/misc@none@none@none@wait,required";
367 CreateTestFile(BOOT_CMD_LINE, cmdLineHasntSn);
368 }
369
PrepareAreaSizeFile()370 void PrepareAreaSizeFile()
371 {
372 // for cmdline
373 const char *ohosParamSize = "default_param=1024"
374 "hilog_param=2048"
375 "const_product_param=2048"
376 "startup_param=20480"
377 "persist_param=2048"
378 "const_param=20480"
379 "persist_sys_param=2048";
380 CreateTestFile(PARAM_AREA_SIZE_CFG, ohosParamSize);
381 }
382
PrepareInitUnitTestEnv(void)383 void PrepareInitUnitTestEnv(void)
384 {
385 static int evnOk = 0;
386 if (evnOk) {
387 return;
388 }
389 PARAM_LOGI("PrepareInitUnitTestEnv");
390 mkdir(STARTUP_INIT_UT_PATH, S_IRWXU | S_IRWXG | S_IRWXO);
391 PrepareUeventdcfg();
392 PrepareInnerKitsCfg();
393 PrepareModCfg();
394 PrepareGroupTestCfg();
395
396 #if !(defined __LITEOS_A__ || defined __LITEOS_M__)
397 // for dac
398 std::string dacData = "ohos.servicectrl. = system:servicectrl:0775 \n";
399 dacData += "test.permission. = root:root:0770\n";
400 dacData += "test.permission.read. = root:root:0774\n";
401 dacData += "test.permission.write.= root:root:0772\n";
402 dacData += "test.permission.watcher. = root:root:0771\n";
403 CreateTestFile(STARTUP_INIT_UT_PATH "/system/etc/param/ohos.para.dac", dacData.c_str());
404 CreateTestFile(STARTUP_INIT_UT_PATH"/trigger_test.cfg", g_triggerData);
405 PrepareAreaSizeFile();
406 #endif
407 InitParamService();
408
409 #if !(defined __LITEOS_A__ || defined __LITEOS_M__)
410 PrepareCmdLineHasSn();
411 TestSetSelinuxOps();
412 LoadSpecialParam();
413 #endif
414
415 // read system parameters
416 LoadDefaultParams("/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
417 LoadDefaultParams("/vendor/etc/param", LOAD_PARAM_NORMAL);
418 LoadDefaultParams("/system/etc/param", LOAD_PARAM_ONLY_ADD);
419 // read ut parameters
420 LoadDefaultParams(STARTUP_INIT_UT_PATH "/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
421 LoadDefaultParams(STARTUP_INIT_UT_PATH "/vendor/etc/param", LOAD_PARAM_NORMAL);
422 LoadDefaultParams(STARTUP_INIT_UT_PATH "/system/etc/param", LOAD_PARAM_ONLY_ADD);
423 LoadParamsFile(STARTUP_INIT_UT_PATH "/system/etc/param", true);
424 LoadParamFromCfg();
425
426 // for test int get
427 SystemWriteParam("test.int.get", "-101");
428 SystemWriteParam("test.uint.get", "101");
429 SystemWriteParam("test.string.get", "101");
430 SystemWriteParam("test.bool.get.true", "true");
431 SystemWriteParam("test.bool.get.false", "false");
432 evnOk = 1;
433 }
434
TestCheckParamPermission(const ParamSecurityLabel * srcLabel,const char * name,uint32_t mode)435 int TestCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
436 {
437 // DAC_RESULT_FORBIDED
438 return g_testPermissionResult;
439 }
440
TestFreeLocalSecurityLabel(ParamSecurityLabel * srcLabel)441 int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel)
442 {
443 return 0;
444 }
445
ParamTestStubInit(void)446 static __attribute__((constructor(101))) void ParamTestStubInit(void)
447 {
448 EnableInitLog(INIT_DEBUG);
449 SetInitLogLevel(INIT_DEBUG);
450 PARAM_LOGI("ParamTestStubInit");
451 PrepareInitUnitTestEnv();
452 }
453 #ifdef __cplusplus
454 #if __cplusplus
455 }
456 #endif
457 #endif
458