param_stub.cpp 16.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "param_stub.h"
#include <dirent.h>
18
#include "init_log.h"
19 20 21 22 23
#include "init_param.h"
#include "param_manager.h"
#include "param_security.h"
#include "param_utils.h"
#include "init_group_manager.h"
24
#include "beget_ext.h"
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#ifdef PARAM_LOAD_CFG_FROM_CODE
#include "param_cfg.h"
#endif

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
int LoadParamFromCmdLine(void);
static int g_testPermissionResult = DAC_RESULT_PERMISSION;
void SetTestPermissionResult(int result)
{
    g_testPermissionResult = result;
}

static const char *selinuxLabels[][2] = {
    {"test.permission.read", "test.persmission.read"},
    {"test.permission.write", "test.persmission.write"},
    {"test.permission.watch", "test.persmission.watch"}
};

static int TestGenHashCode(const char *buff)
{
    int code = 0;
    size_t buffLen = strlen(buff);
    for (size_t i = 0; i < buffLen; i++) {
        code += buff[i] - 'A';
    }
    return code;
}

static void TestSetSelinuxLogCallback(void) {}

R
renwei 已提交
59
static int TestSetParamCheck(const char *paraName, const char *context, const SrcInfo *info)
60
{
C
cheng_jinsong 已提交
61
    BEGET_LOGI("TestSetParamCheck %s result %d", paraName, g_testPermissionResult);
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    return g_testPermissionResult;
}

static const char *TestGetParamLabel(const char *paraName)
{
    BEGET_LOGI("TestGetParamLabel %s", paraName);
    for (size_t i = 0; i < ARRAY_LENGTH(selinuxLabels); i++) {
        if (strncmp(selinuxLabels[i][0], paraName, strlen(selinuxLabels[i][0])) == 0) {
            return selinuxLabels[i][1];
        }
    }
    int code = TestGenHashCode(paraName);
    code = code % (ARRAY_LENGTH(selinuxLabels));
    return selinuxLabels[code][1];
}

78
static const char *g_forbidReadParamName[] = {
79 80 81 82 83 84
    "ohos.servicectrl.",
    // "test.permission.write",
};
static int TestReadParamCheck(const char *paraName)
{
    // forbid to read ohos.servicectrl.
85 86
    for (size_t i = 0; i < ARRAY_LENGTH(g_forbidReadParamName); i++) {
        if (strncmp(paraName, g_forbidReadParamName[i], strlen(g_forbidReadParamName[i])) == 0) {
87 88 89 90 91 92 93 94 95 96 97
            return 1;
        }
    }
    return g_testPermissionResult;
}
static void TestDestroyParamList(ParamContextsList **list)
{
#ifdef PARAM_SUPPORT_SELINUX
    ParamContextsList *head = *list;
    while (head != nullptr) {
        ParamContextsList *next = head->next;
A
an_xinwei 已提交
98 99
        free((void *)head->info.paraName);
        free((void *)head->info.paraContext);
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
        free(head);
        head = next;
    }
#endif
}
static ParamContextsList *TestGetParamList(void)
{
#ifdef PARAM_SUPPORT_SELINUX
    ParamContextsList *head = (ParamContextsList *)malloc(sizeof(ParamContextsList));
    BEGET_ERROR_CHECK(head != nullptr, return nullptr, "Failed to alloc ParamContextsList");
    head->info.paraName = strdup(selinuxLabels[0][0]);
    head->info.paraContext = strdup(selinuxLabels[0][1]);
    head->next = nullptr;
    for (size_t i = 1; i < ARRAY_LENGTH(selinuxLabels); i++) {
        ParamContextsList *node = (ParamContextsList *)malloc(sizeof(ParamContextsList));
        BEGET_ERROR_CHECK(node != nullptr, TestDestroyParamList(&head);
            return nullptr, "Failed to alloc ParamContextsList");
        node->info.paraName = strdup(selinuxLabels[i][0]);
        node->info.paraContext = strdup(selinuxLabels[i][1]);
        node->next = head->next;
        head->next = node;
    }
    return head;
#else
    return nullptr;
#endif
}

void TestSetSelinuxOps(void)
{
#ifdef PARAM_SUPPORT_SELINUX
A
an_xinwei 已提交
131 132 133 134 135 136 137
    SelinuxSpace *selinuxSpace = &GetParamWorkSpace()->selinuxSpace;
    selinuxSpace->setSelinuxLogCallback = TestSetSelinuxLogCallback;
    selinuxSpace->setParamCheck = TestSetParamCheck;
    selinuxSpace->getParamLabel = TestGetParamLabel;
    selinuxSpace->readParamCheck = TestReadParamCheck;
    selinuxSpace->getParamList = TestGetParamList;
    selinuxSpace->destroyParamList = TestDestroyParamList;
138 139
#endif
}
C
cheng_jinsong 已提交
140 141 142 143 144 145 146 147 148 149 150 151

void TestSetParamCheckResult(const char *prefix, uint16_t mode, int result)
{
    ParamAuditData auditData = {};
    auditData.name = prefix;
    auditData.dacData.gid = 202;  // 202 test dac gid
    auditData.dacData.uid = 202;  // 202 test dac uid
    auditData.dacData.mode = mode;
    AddSecurityLabel(&auditData);
    SetTestPermissionResult(result);
}

152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
static void CreateTestFile(const char *fileName, const char *data)
{
    CheckAndCreateDir(fileName);
    PARAM_LOGV("PrepareParamTestData for %s", fileName);
    FILE *tmpFile = fopen(fileName, "wr");
    if (tmpFile != nullptr) {
        fprintf(tmpFile, "%s", data);
        (void)fflush(tmpFile);
        fclose(tmpFile);
    }
}
static void PrepareUeventdcfg(void)
{
    const char *ueventdcfg = "[device]\n"
        "/dev/test 0666 1000 1000\n"
        "[device]\n"
        "/dev/test1 0666 1000\n"
        "[device]\n"
        "/dev/test2 0666 1000 1000 1000 1000\n"
        "[sysfs]\n"
        "/dir/to/nothing attr_nowhere 0666 1000 1000\n"
        "[sysfs]\n"
        "  #/dir/to/nothing attr_nowhere 0666\n"
        "[sysfs\n"
        "/dir/to/nothing attr_nowhere 0666\n"
        "[firmware]\n"
        "/etc\n"
        "[device]\n"
        "/dev/testbinder 0666 1000 1000 const.dev.binder\n"
        "[device]\n"
        "/dev/testbinder1 0666 1000 1000 const.dev.binder\n"
        "[device]\n"
        "/dev/testbinder2 0666 1000 1000 const.dev.binder\n"
        "[device]\n"
        "/dev/testbinder3 0666 1000 1000 const.dev.binder\n";
    mkdir("/data/ueventd_ut", S_IRWXU | S_IRWXG | S_IRWXO);
    CreateTestFile("/data/ueventd_ut/valid.config", ueventdcfg);
}
static void PrepareModCfg(void)
{
    const char *modCfg = "testinsmod";
    CreateTestFile("/data/init_ut/test_insmod", modCfg);
}
static void PrepareInnerKitsCfg()
{
    const char *innerKitsCfg = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/system /system "
        "ext4 ro,barrier=1 wait\n"
        "/dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor "
        "ext4 ro,barrier=1 wait\n"
        "/dev/block/platform/soc/10100000.himci.eMMC/by-name/hos "
        "/hos ntfs nosuid,nodev,noatime,barrier=1,data=ordered wait\n"
        "/dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data ext4 "
        "nosuid,nodev,noatime,barrier=1,data=ordered,noauto_da_alloc "
        "wait,reservedsize=104857600\n"
        "  aaaa\n"
        "aa aa\n"
        "aa aa aa\n"
        "aa aa aa aa\n";
C
chengjinsong 已提交
210 211
    const char *fstabRequired = "# fstab file.\n"
        "#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>\n"
C
chengjinsong 已提交
212
        "/dev/block/platform/fe310000.sdhci/by-name/testsystem /usr ext4 ro,barrier=1 wait,required,nofail\n"
C
chengjinsong 已提交
213 214 215 216
        "/dev/block/platform/fe310000.sdhci/by-name/testvendor /vendor ext4 ro,barrier=1 wait,required\n"
        "/dev/block/platform/fe310000.sdhci/by-name/testuserdata1 /data f2fs noatime,nosuid,nodev wait,check,quota\n"
        "/dev/block/platform/fe310000.sdhci/by-name/testuserdata2 /data ext4 noatime,fscrypt=xxx wait,check,quota\n"
        "/dev/block/platform/fe310000.sdhci/by-name/testmisc /misc none none wait,required";
217 218
    mkdir("/data/init_ut/mount_unitest/", S_IRWXU | S_IRWXG | S_IRWXO);
    CreateTestFile("/data/init_ut/mount_unitest/ReadFstabFromFile1.fstable", innerKitsCfg);
C
chengjinsong 已提交
219
    CreateTestFile("/data/init_ut/etc/fstab.required", fstabRequired);
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
}
static void PrepareGroupTestCfg()
{
    const char *data = "{"
	    "\"jobs\": [\"param:job1\", \"param:job2\", \"param:job4\"],"
	    "\"services\": [\"service:service1\", \"service:service3\", \"service:service2\"],"
	    "\"groups\": [\"subsystem.xxx1.group\", \"subsystem.xxx2.group\", \"subsystem.xxx4.group\"]"
    "}";
    const char *xxx1 = "{"
	    "\"groups\": [\"subsystem.xxx11.group\""
    "}";
    const char *xxx11 = "{"
	    "\"groups\": [\"subsystem.xxx12.group\""
    "}";
    const char *xxx12 = "{"
	    "\"groups\": [\"subsystem.xxx13.group\""
    "}";
    const char *xxx13 = "{"
	    "\"groups\": [\"subsystem.xxx14.group\""
    "}";
    const char *xxx14 = "{"
	    "\"groups\": [\"subsystem.xxx11.group\""
    "}";
    CreateTestFile(GROUP_DEFAULT_PATH "/device.boot.group.cfg", data);
    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx1.group.cfg", xxx1);
    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx11.group.cfg", xxx11);
    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx12.group.cfg", xxx12);
    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx13.group.cfg", xxx13);
    CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx14.group.cfg", xxx14);
}
static bool IsDir(const std::string &path)
{
    struct stat st {};
    if (stat(path.c_str(), &st) < 0) {
        return false;
    }
    return S_ISDIR(st.st_mode);
}
static bool DeleteDir(const std::string &path)
{
    auto pDir = std::unique_ptr<DIR, decltype(&closedir)>(opendir(path.c_str()), closedir);
    if (pDir == nullptr) {
        return false;
    }

    struct dirent *dp = nullptr;
    while ((dp = readdir(pDir.get())) != nullptr) {
        std::string currentName(dp->d_name);
        if (currentName[0] != '.') {
            std::string tmpName(path);
            tmpName.append("/" + currentName);
            if (IsDir(tmpName)) {
                DeleteDir(tmpName);
            }
            remove(tmpName.c_str());
        }
    }
    if (remove(path.c_str()) != 0) {
        return false;
    }
    return true;
}
static void LoadParamFromCfg(void)
{
#ifdef PARAM_LOAD_CFG_FROM_CODE
    for (size_t i = 0; i < ARRAY_LENGTH(g_paramDefCfgNodes); i++) {
        PARAM_LOGI("InitParamClient name %s = %s", g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value);
        uint32_t dataIndex = 0;
        int ret = WriteParam(g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value, &dataIndex, 0);
        PARAM_CHECK(ret == 0, continue, "Failed to set param %d name %s %s",
            ret, g_paramDefCfgNodes[i].name, g_paramDefCfgNodes[i].value);
    }
#endif
}
#if !(defined __LITEOS_A__ || defined __LITEOS_M__)
static const char *g_triggerData = "{"
        "\"jobs\" : [{"
        "        \"name\" : \"early-init\","
        "        \"cmds\" : ["
        "            \"    write        '/proc/sys/kernel/sysrq 0'\","
        "            \"    load_persist_params \","
        "            \"    load_persist_params        \","
        "            \" #   load_persist_params \","
        "            \"   restorecon /postinstall\","
        "            \"mkdir /acct/uid\","
        "            \"chown root system /dev/memcg/memory.pressure_level\","
        "            \"chmod 0040 /dev/memcg/memory.pressure_level\","
        "            \"mkdir /dev/memcg/apps/ 0755 system system\","
        "           \"mkdir /dev/memcg/system 0550 system system\","
        "            \"start ueventd\","
        "            \"exec_start apexd-bootstrap\","
        "            \"setparam sys.usb.config ${persist.sys.usb.config}\""
        "        ]"
        "    },"
        "    {"
        "        \"name\" : \"param:trigger_test_1\","
        "        \"condition\" : \"test.sys.boot_from_charger_mode=5\","
        "        \"cmds\" : ["
        "            \"class_stop charger\","
        "            \"trigger late-init\""
        "        ]"
        "    },"
        "    {"
        "        \"name\" : \"param:trigger_test_2\","
        "        \"condition\" : \"test.sys.boot_from_charger_mode=1  "
        " || test.sys.boot_from_charger_mode=2   ||  test.sys.boot_from_charger_mode=3\","
        "        \"cmds\" : ["
        "            \"class_stop charger\","
        "            \"trigger late-init\""
        "        ]"
        "    },"
        "    {"
        "        \"name\" : \"load_persist_params_action\","
        "        \"cmds\" : ["
        "           \"load_persist_params\","
        "            \"start logd\","
        "            \"start logd-reinit\""
        "        ]"
        "    },"
        "    {"
        "        \"name\" : \"firmware_mounts_complete\","
        "        \"cmds\" : ["
        "            \"rm /dev/.booting\""
        "        ]"
        "    }"
        "]"
    "}";
#endif

void PrepareCmdLineHasSn()
{
    // for cmdline
    const char *cmdLineHasSnroot = "bootgroup=device.charge.group earlycon=uart8250,mmio32,0xfe660000 "
        "root=PARTUUID=614e0000-0000 rw rootwait rootfstype=ext4 console=ttyFIQ0 hardware=rk3568"
C
slot  
chengjinsong 已提交
354
        " BOOT_IMAGE=/kernel ohos.boot.sn=/test init=/init";
355 356 357
    CreateTestFile(BOOT_CMD_LINE, cmdLineHasSnroot);
    LoadParamFromCmdLine();
    const char *cmdLineHasntSn = "bootgroup=device.charge.group earlycon=uart8250,mmio32,0xfe660000 "
C
slot  
chengjinsong 已提交
358
        "root=PARTUUID=614e0000-0000 rw rootwait rootfstype=ext4 console=ttyFIQ0 hardware=rk3568 "
C
cheng_jinsong 已提交
359
        "BOOT_IMAGE=/kernel init=/init default_boot_device=fe310000.sdhci bootslots=2 currentslot=1 "
C
slot  
chengjinsong 已提交
360 361 362 363 364 365
        "ohos.required_mount.system="
        "/dev/block/platform/fe310000.sdhci/by-name/system@/usr@ext4@ro,barrier=1@wait,required "
        "ohos.required_mount.vendor="
        "/dev/block/platform/fe310000.sdhci/by-name/vendor@/vendor@ext4@ro,barrier=1@wait,required "
        "ohos.required_mount.misc="
        "/dev/block/platform/fe310000.sdhci/by-name/misc@none@none@none@wait,required";
366 367 368
    CreateTestFile(BOOT_CMD_LINE, cmdLineHasntSn);
}

C
cheng_jinsong 已提交
369 370 371 372 373 374 375 376 377 378 379 380 381
void PrepareAreaSizeFile()
{
    // for cmdline
    const char *ohosParamSize = "default_param=1024"
            "hilog_param=2048"
            "const_product_param=2048"
            "startup_param=20480"
            "persist_param=2048"
            "const_param=20480"
            "persist_sys_param=2048";
    CreateTestFile(PARAM_AREA_SIZE_CFG, ohosParamSize);
}

382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
void PrepareInitUnitTestEnv(void)
{
    static int evnOk = 0;
    if (evnOk) {
        return;
    }
    PARAM_LOGI("PrepareInitUnitTestEnv");
    mkdir(STARTUP_INIT_UT_PATH, S_IRWXU | S_IRWXG | S_IRWXO);
    PrepareUeventdcfg();
    PrepareInnerKitsCfg();
    PrepareModCfg();
    PrepareGroupTestCfg();

#if !(defined __LITEOS_A__ || defined __LITEOS_M__)
    // for dac
    std::string dacData = "ohos.servicectrl.   = system:servicectrl:0775 \n";
    dacData += "test.permission.       = root:root:0770\n";
    dacData += "test.permission.read. =  root:root:0774\n";
    dacData += "test.permission.write.=  root:root:0772\n";
    dacData += "test.permission.watcher. = root:root:0771\n";
    CreateTestFile(STARTUP_INIT_UT_PATH "/system/etc/param/ohos.para.dac", dacData.c_str());
    CreateTestFile(STARTUP_INIT_UT_PATH"/trigger_test.cfg", g_triggerData);
C
cheng_jinsong 已提交
404
    PrepareAreaSizeFile();
405 406 407
#endif
    InitParamService();

M
Mupceet 已提交
408 409 410 411 412 413
#if !(defined __LITEOS_A__ || defined __LITEOS_M__)
    PrepareCmdLineHasSn();
    TestSetSelinuxOps();
    LoadSpecialParam();
#endif

414 415 416 417 418 419 420 421 422
    // read system parameters
    LoadDefaultParams("/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
    LoadDefaultParams("/vendor/etc/param", LOAD_PARAM_NORMAL);
    LoadDefaultParams("/system/etc/param", LOAD_PARAM_ONLY_ADD);
    // read ut parameters
    LoadDefaultParams(STARTUP_INIT_UT_PATH "/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
    LoadDefaultParams(STARTUP_INIT_UT_PATH "/vendor/etc/param", LOAD_PARAM_NORMAL);
    LoadDefaultParams(STARTUP_INIT_UT_PATH "/system/etc/param", LOAD_PARAM_ONLY_ADD);
    LoadParamFromCfg();
C
cheng_jinsong 已提交
423 424 425 426 427 428 429

    // for test int get
    SystemWriteParam("test.int.get", "-101");
    SystemWriteParam("test.uint.get", "101");
    SystemWriteParam("test.string.get", "101");
    SystemWriteParam("test.bool.get.true", "true");
    SystemWriteParam("test.bool.get.false", "false");
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
    evnOk = 1;
}

int TestCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
{
    // DAC_RESULT_FORBIDED
    return g_testPermissionResult;
}

int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel)
{
    return 0;
}

static __attribute__((constructor(101))) void ParamTestStubInit(void)
{
C
cheng_jinsong 已提交
446
    EnableInitLog(INIT_DEBUG);
447
    SetInitLogLevel(INIT_DEBUG);
448 449 450 451 452 453 454 455
    PARAM_LOGI("ParamTestStubInit");
    PrepareInitUnitTestEnv();
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif