param_selinux.c 7.0 KB
Newer Older
S
sun_fan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * 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.
 */
M
Mupceet 已提交
15
#include <dlfcn.h>
S
sun_fan 已提交
16
#include <sys/stat.h>
M
Mupceet 已提交
17
#include <sys/socket.h>
S
sun_fan 已提交
18

19
#include "init_utils.h"
M
Mupceet 已提交
20
#include "param_manager.h"
S
sun_fan 已提交
21 22
#include "param_security.h"
#include "param_utils.h"
M
Mupceet 已提交
23 24 25
#ifdef PARAM_SUPPORT_SELINUX
#include "selinux_parameter.h"
#endif
S
sun_fan 已提交
26

M
Mupceet 已提交
27 28 29 30 31 32
#ifdef __aarch64__
#define CHECKER_LIB_NAME "/system/lib64/libparaperm_checker.z.so"
#else
#define CHECKER_LIB_NAME "/system/lib/libparaperm_checker.z.so"
#endif

M
Mupceet 已提交
33 34
static SelinuxSpace g_selinuxSpace = {0};
static int InitLocalSecurityLabel(ParamSecurityLabel *security, int isInit)
S
sun_fan 已提交
35 36
{
    UNUSED(isInit);
M
Mupceet 已提交
37 38 39 40 41 42 43
    PARAM_CHECK(security != NULL, return -1, "Invalid security");
    security->cred.pid = getpid();
    security->cred.uid = geteuid();
    security->cred.gid = getegid();
    security->flags[PARAM_SECURITY_SELINUX] = 0;
#if !(defined STARTUP_INIT_TEST || defined LOCAL_TEST)
    if (g_selinuxSpace.selinuxHandle == NULL) {
M
Mupceet 已提交
44
        g_selinuxSpace.selinuxHandle = dlopen(CHECKER_LIB_NAME, RTLD_LAZY);
M
Mupceet 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58
        PARAM_CHECK(g_selinuxSpace.selinuxHandle != NULL,
            return -1, "Failed to dlsym selinuxHandle, %s", dlerror());
    }
    void *handle = g_selinuxSpace.selinuxHandle;
    if (g_selinuxSpace.setSelinuxLogCallback == NULL) {
        g_selinuxSpace.setSelinuxLogCallback = (void (*)())dlsym(handle, "SetSelinuxLogCallback");
        PARAM_CHECK(g_selinuxSpace.setSelinuxLogCallback != NULL,
            return -1, "Failed to dlsym setSelinuxLogCallback %s", dlerror());
    }
    if (g_selinuxSpace.setParamCheck == NULL) {
        g_selinuxSpace.setParamCheck = (SelinuxSetParamCheck)dlsym(handle, "SetParamCheck");
        PARAM_CHECK(g_selinuxSpace.setParamCheck != NULL, return -1, "Failed to dlsym setParamCheck %s", dlerror());
    }
    if (g_selinuxSpace.getParamList == NULL) {
M
Mupceet 已提交
59
        g_selinuxSpace.getParamList = (ParamContextsList *(*)()) dlsym(handle, "GetParamList");
M
Mupceet 已提交
60 61 62
        PARAM_CHECK(g_selinuxSpace.getParamList != NULL, return -1, "Failed to dlsym getParamList %s", dlerror());
    }
    if (g_selinuxSpace.getParamLabel == NULL) {
M
Mupceet 已提交
63
        g_selinuxSpace.getParamLabel = (const char * (*)(const char *))dlsym(handle, "GetParamLabel");
M
Mupceet 已提交
64 65 66 67 68 69 70 71 72 73 74 75
        PARAM_CHECK(g_selinuxSpace.getParamLabel != NULL, return -1, "Failed to dlsym getParamLabel %s", dlerror());
    }
    if (g_selinuxSpace.readParamCheck == NULL) {
        g_selinuxSpace.readParamCheck = (int (*)(const char *))dlsym(handle, "ReadParamCheck");
        PARAM_CHECK(g_selinuxSpace.readParamCheck != NULL, return -1, "Failed to dlsym readParamCheck %s", dlerror());
    }
    if (g_selinuxSpace.destroyParamList == NULL) {
        g_selinuxSpace.destroyParamList =
            (void (*)(ParamContextsList **))dlsym(handle, "DestroyParamList");
        PARAM_CHECK(g_selinuxSpace.destroyParamList != NULL,
            return -1, "Failed to dlsym destroyParamList %s", dlerror());
    }
L
laiguizhong 已提交
76 77 78 79
    if (isInit) {
        // log
        g_selinuxSpace.setSelinuxLogCallback();
    }
M
Mupceet 已提交
80 81
#endif
    PARAM_LOGV("Load sulinux lib success.");
S
sun_fan 已提交
82 83 84 85 86 87 88 89
    return 0;
}

static int FreeLocalSecurityLabel(ParamSecurityLabel *srcLabel)
{
    return 0;
}

M
Mupceet 已提交
90
static int SelinuxGetParamSecurityLabel(const char *path)
S
sun_fan 已提交
91
{
M
Mupceet 已提交
92 93 94 95 96 97 98 99 100
    UNUSED(path);
    PARAM_CHECK(g_selinuxSpace.getParamList != NULL, return DAC_RESULT_FORBIDED, "Invalid getParamList");
    ParamContextsList *head = g_selinuxSpace.getParamList();
    ParamContextsList *node = head;
    int count = 0;
    while (node != NULL) {
        PARAM_LOGV("GetParamSecurityLabel name %s content %s", node->info.paraName, node->info.paraContext);
        if (node->info.paraContext == NULL || node->info.paraName == NULL) {
            node = node->next;
S
sun_fan 已提交
101 102
            continue;
        }
M
Mupceet 已提交
103 104 105 106 107
        int ret = AddWorkSpace(node->info.paraContext, 0, PARAM_WORKSPACE_DEF);
        PARAM_CHECK(ret == 0, continue,
            "Failed to add selinx workspace %s %s", node->info.paraName, node->info.paraContext);
        node = node->next;
        count++;
4
411148299@qq.com 已提交
108
    }
M
Mupceet 已提交
109 110 111 112
    g_selinuxSpace.destroyParamList(&head);
    int ret = AddWorkSpace(WORKSPACE_NAME_DEF_SELINUX, 0, PARAM_WORKSPACE_MAX);
    PARAM_CHECK(ret == 0, return -1,
        "Failed to add selinx workspace %s %s", node->info.paraName, node->info.paraContext);
S
sun_fan 已提交
113

M
Mupceet 已提交
114
    return 0;
S
sun_fan 已提交
115 116 117 118 119 120 121 122 123
}

static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char *fileName, int flags)
{
    UNUSED(flags);
    PARAM_CHECK(localLabel != NULL && fileName != NULL, return -1, "Invalid param");
    return 0;
}

M
Mupceet 已提交
124
static int SelinuxCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
S
sun_fan 已提交
125
{
M
Mupceet 已提交
126 127 128 129 130 131 132 133 134 135 136 137
    int ret = DAC_RESULT_FORBIDED;
    PARAM_CHECK(g_selinuxSpace.setParamCheck != NULL, return ret, "Invalid setParamCheck");
    PARAM_CHECK(g_selinuxSpace.readParamCheck != NULL, return ret, "Invalid readParamCheck");

    // check
    struct ucred uc;
    uc.pid = srcLabel->cred.pid;
    uc.uid = srcLabel->cred.uid;
    uc.gid = srcLabel->cred.gid;
    if (mode == DAC_WRITE) {
        ret = g_selinuxSpace.setParamCheck(name, &uc);
    } else {
L
laiguizhong 已提交
138
        ret = 0;
M
Mupceet 已提交
139 140 141 142 143
    }
    if (ret != 0) {
        PARAM_LOGI("Selinux check name %s pid %d uid %d %d result %d", name, uc.pid, uc.uid, uc.gid, ret);
    }
    return ret;
S
sun_fan 已提交
144 145
}

M
Mupceet 已提交
146
int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit)
S
sun_fan 已提交
147 148
{
    PARAM_CHECK(ops != NULL, return -1, "Invalid param");
M
Mupceet 已提交
149
    int ret = strcpy_s(ops->name, sizeof(ops->name), "selinux");
S
sun_fan 已提交
150 151 152
    ops->securityGetLabel = NULL;
    ops->securityInitLabel = InitLocalSecurityLabel;
    ops->securityCheckFilePermission = CheckFilePermission;
M
Mupceet 已提交
153
    ops->securityCheckParamPermission = SelinuxCheckParamPermission;
S
sun_fan 已提交
154 155
    ops->securityFreeLabel = FreeLocalSecurityLabel;
    if (isInit) {
M
Mupceet 已提交
156
        ops->securityGetLabel = SelinuxGetParamSecurityLabel;
S
sun_fan 已提交
157
    }
M
Mupceet 已提交
158
    return ret;
S
sun_fan 已提交
159
}
M
Mupceet 已提交
160

M
Mupceet 已提交
161
const char *GetSelinuxContent(const char *name)
M
Mupceet 已提交
162 163
{
    PARAM_CHECK(g_selinuxSpace.getParamLabel != NULL, return NULL, "Invalid getParamLabel");
M
Mupceet 已提交
164
    return g_selinuxSpace.getParamLabel(name);
M
Mupceet 已提交
165 166 167 168
}

#if defined STARTUP_INIT_TEST || defined LOCAL_TEST
void SetSelinuxOps(const SelinuxSpace *space)
S
sun_fan 已提交
169
{
M
Mupceet 已提交
170 171 172 173 174 175
    g_selinuxSpace.setSelinuxLogCallback = space->setSelinuxLogCallback;
    g_selinuxSpace.setParamCheck = space->setParamCheck;
    g_selinuxSpace.getParamLabel = space->getParamLabel;
    g_selinuxSpace.readParamCheck = space->readParamCheck;
    g_selinuxSpace.getParamList = space->getParamList;
    g_selinuxSpace.destroyParamList = space->destroyParamList;
S
sun_fan 已提交
176 177
}
#endif