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