selinux_adp.c 4.9 KB
Newer Older
C
cheng_jinsong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright (c) 2022 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 "selinux_adp.h"

#include <errno.h>

#include "init_hook.h"
#include "init_module_engine.h"
#include "plugin_adapter.h"
22
#include "securec.h"
C
cheng_jinsong 已提交
23 24 25 26

#include <policycoreutils.h>
#include <selinux/selinux.h>

R
renwei 已提交
27 28 29 30 31 32 33
enum {
    CMD_LOAD_POLICY = 0,
    CMD_SET_SERVICE_CONTEXTS = 1,
    CMD_SET_SOCKET_CONTEXTS = 2,
    CMD_RESTORE_INDEX = 3,
};

34 35
extern char *__progname;

C
cheng_jinsong 已提交
36 37
static int LoadSelinuxPolicy(int id, const char *name, int argc, const char **argv)
{
38 39 40
    int ret;
    char process_context[MAX_SECON_LEN];

C
cheng_jinsong 已提交
41 42 43 44 45 46 47 48 49 50 51 52
    UNUSED(id);
    UNUSED(name);
    UNUSED(argc);
    UNUSED(argv);
    PLUGIN_LOGI("LoadSelinuxPolicy ");
    // load selinux policy and context
    if (LoadPolicy() < 0) {
        PLUGIN_LOGE("main, load_policy failed.");
    } else {
        PLUGIN_LOGI("main, load_policy success.");
    }

53 54 55 56 57 58
    ret = snprintf_s(process_context, sizeof(process_context), sizeof(process_context) - 1, "u:r:%s:s0", __progname);
    if (ret == -1) {
        setcon("u:r:init:s0");
    } else {
        setcon(process_context);
    }
C
cheng_jinsong 已提交
59 60 61 62 63 64 65 66 67 68 69
    (void)RestoreconRecurse("/dev");
    return 0;
}

static int SetServiceContent(int id, const char *name, int argc, const char **argv)
{
    PLUGIN_CHECK(name != NULL && argc >= 1 && argv != NULL, return -1, "Invalid parameter");
    ServiceExtData *data = GetServiceExtData(argv[0], HOOK_ID_SELINUX);
    if (data != NULL) {
        if (setexeccon((char *)data->data) < 0) {
            PLUGIN_LOGE("failed to set service %s's secon (%s).", argv[0], (char *)data->data);
C
cheng_jinsong 已提交
70
#ifndef STARTUP_INIT_TEST
C
cheng_jinsong 已提交
71
            _exit(PROCESS_EXIT_CODE);
C
cheng_jinsong 已提交
72
#endif
C
cheng_jinsong 已提交
73
        } else {
C
fix log  
cheng_jinsong 已提交
74
            PLUGIN_LOGV("Set content %s to %s.", (char *)data->data, argv[0]);
C
cheng_jinsong 已提交
75 76 77 78 79 80 81 82 83
        }
    } else {
        PLUGIN_CHECK(!(setexeccon("u:r:limit_domain:s0") < 0), _exit(PROCESS_EXIT_CODE),
            "failed to set service %s's secon (%s).", argv[0], "u:r:limit_domain:s0");
        PLUGIN_LOGE("Please set secon field in service %s's cfg file, limit_domain will be blocked", argv[0]);
    }
    return 0;
}

R
renwei 已提交
84 85
static int SetSockCreateCon(int id, const char *name, int argc, const char **argv)
{
C
cheng_jinsong 已提交
86 87
    PLUGIN_CHECK(name != NULL, return -1, "Invalid parameter");
    if (argc == 0) {
R
renwei 已提交
88 89 90
        setsockcreatecon(NULL);
        return 0;
    }
C
cheng_jinsong 已提交
91
    PLUGIN_CHECK(argc >= 1 && argv != NULL, return -1, "Invalid parameter");
R
renwei 已提交
92 93 94 95
    ServiceExtData *data = GetServiceExtData(argv[0], HOOK_ID_SELINUX);
    if (data != NULL) {
        if (setsockcreatecon((char *)data->data) < 0) {
            PLUGIN_LOGE("failed to set socket context %s's secon (%s).", argv[0], (char *)data->data);
C
cheng_jinsong 已提交
96
#ifndef STARTUP_INIT_TEST
R
renwei 已提交
97
            _exit(PROCESS_EXIT_CODE);
C
cheng_jinsong 已提交
98
#endif
R
renwei 已提交
99 100 101 102 103 104
        }
    }

    return 0;
}

C
cheng_jinsong 已提交
105 106 107 108 109 110 111 112 113 114
static int RestoreContentRecurse(int id, const char *name, int argc, const char **argv)
{
    PLUGIN_CHECK(name != NULL && argc >= 1 && argv != NULL, return -1, "Invalid parameter");
    PLUGIN_LOGV("RestoreContentRecurse path %s", argv[0]);
    if (RestoreconRecurse(argv[0])) {
        PLUGIN_LOGE("restoreContentRecurse failed for '%s', err %d.", argv[0], errno);
    }
    return 0;
}

R
renwei 已提交
115
static int32_t selinuxAdpCmdIds[CMD_RESTORE_INDEX + 1] = {0}; // 4 cmd count
C
cheng_jinsong 已提交
116 117
static void SelinuxAdpInit(void)
{
R
renwei 已提交
118 119 120
    selinuxAdpCmdIds[CMD_LOAD_POLICY] = AddCmdExecutor("loadSelinuxPolicy", LoadSelinuxPolicy);
    selinuxAdpCmdIds[CMD_SET_SERVICE_CONTEXTS] = AddCmdExecutor("setServiceContent", SetServiceContent);
    selinuxAdpCmdIds[CMD_SET_SOCKET_CONTEXTS] = AddCmdExecutor("setSockCreateCon", SetSockCreateCon);
C
cheng_jinsong 已提交
121 122 123 124 125
    selinuxAdpCmdIds[CMD_RESTORE_INDEX] = AddCmdExecutor("restoreContentRecurse", RestoreContentRecurse);
}

static void SelinuxAdpExit(void)
{
R
renwei 已提交
126 127
    if (selinuxAdpCmdIds[CMD_LOAD_POLICY] != -1) {
        RemoveCmdExecutor("loadSelinuxPolicy", selinuxAdpCmdIds[CMD_LOAD_POLICY]);
C
cheng_jinsong 已提交
128
    }
R
renwei 已提交
129 130 131 132 133
    if (selinuxAdpCmdIds[CMD_SET_SERVICE_CONTEXTS] != -1) {
        RemoveCmdExecutor("setServiceContent", selinuxAdpCmdIds[CMD_SET_SERVICE_CONTEXTS]);
    }
    if (selinuxAdpCmdIds[CMD_SET_SOCKET_CONTEXTS] != -1) {
        RemoveCmdExecutor("setSockCreateCon", selinuxAdpCmdIds[CMD_SET_SOCKET_CONTEXTS]);
C
cheng_jinsong 已提交
134 135 136 137 138 139 140 141
    }
    if (selinuxAdpCmdIds[CMD_RESTORE_INDEX] != -1) {
        RemoveCmdExecutor("restoreContentRecurse", selinuxAdpCmdIds[CMD_RESTORE_INDEX]);
    }
}

MODULE_CONSTRUCTOR(void)
{
C
fix log  
cheng_jinsong 已提交
142
    PLUGIN_LOGI("Selinux adapter plug-in init now ...");
C
cheng_jinsong 已提交
143 144 145 146 147
    SelinuxAdpInit();
}

MODULE_DESTRUCTOR(void)
{
C
fix log  
cheng_jinsong 已提交
148
    PLUGIN_LOGI("Selinux adapter plug-in exit now ...");
C
cheng_jinsong 已提交
149
    SelinuxAdpExit();
R
renwei 已提交
150
}