【Android】如何配置打开和关闭selinux

直接配置init进程的Android.bp文件和uboot配置的值最佳,Android.bp下面-DALLOW_PERMISSIVE_SELINUX=0则是关闭,=1则是打开;bootloader/uboot-repo/bl33/board/公司名/configs/对应芯片的配置头文件.h,"EnableSelinux=enforcing\0"\是打开,"EnableSelinux=permissive\0"\则是关闭。偷懒则是直接修改selinux.cpp下面的isEnforcing函数。

下面是分析。

先看init初始化selinux的代码。security_getenforce是读取uboot设置的selinux模式,isEnforcing则是读取init Android.mk/Android.bp配置的selinux模式

void SelinuxInitialize() {
    Timer t;

    LOG(INFO) << "Loading SELinux policy";
    if (!LoadPolicy()) {
        LOG(FATAL) << "Unable to load SELinux policy";
    }

    bool kernel_enforcing = (security_getenforce() == 1);
    bool is_enforcing = IsEnforcing();
    if (kernel_enforcing != is_enforcing) {
        if (security_setenforce(is_enforcing)) {
            PLOG(FATAL) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
        }
    }

    if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) {
        LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
    }

    // init's first stage can't set properties, so pass the time to the second stage.
    setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1);
}

isEnforcing里面。ALLOW_PERMISSIVE_SELINUX来自于Android.bp定义的"-DALLOW_PERMISSIVE_SELINUX=0",然后在下面debuggable打开即非user版本则会将其设置为1,即permissvie模式。

system/core/init/selinux.cpp

这里能看到判断系统师傅打开selinux的逻辑。

1.init Android.bp配置-DALLOW_PERMISSIVE_SELINUX=1

2.StatusFromCmdline是读取/proc/cmdline uboot设置的键值对,其中"EnableSelinux=permissive\0"\

bool IsEnforcing() {
    if (ALLOW_PERMISSIVE_SELINUX) {
        return StatusFromCmdline() == SELINUX_ENFORCING;
    }
    return true;
}

 

    cflags: [
        "-DLOG_UEVENTS=0",
        "-Wall",
        "-Wextra",
        "-Wno-unused-parameter",
        "-Werror",
        "-DALLOW_LOCAL_PROP_OVERRIDE=0",
        "-DALLOW_PERMISSIVE_SELINUX=0",
        "-DREBOOT_BOOTLOADER_ON_PANIC=0",
        "-DWORLD_WRITABLE_KMSG=0",
        "-DDUMP_ON_UMOUNT_FAILURE=0",
        "-DSHUTDOWN_ZERO_TIMEOUT=0",
    ],
    product_variables: {
        debuggable: {
            cppflags: [
                "-UALLOW_LOCAL_PROP_OVERRIDE",
                "-DALLOW_LOCAL_PROP_OVERRIDE=1",
                "-UALLOW_PERMISSIVE_SELINUX",
                "-DALLOW_PERMISSIVE_SELINUX=1",
                "-UREBOOT_BOOTLOADER_ON_PANIC",
                "-DREBOOT_BOOTLOADER_ON_PANIC=1",
                "-UWORLD_WRITABLE_KMSG",
                "-DWORLD_WRITABLE_KMSG=1",
                "-UDUMP_ON_UMOUNT_FAILURE",
                "-DDUMP_ON_UMOUNT_FAILURE=1",
            ],
        },
        eng: {
            cppflags: [
                "-USHUTDOWN_ZERO_TIMEOUT",
                "-DSHUTDOWN_ZERO_TIMEOUT=1",
            ],
        },
        uml: {
            cppflags: ["-DUSER_MODE_LINUX"],
        },
    },

而security_getenforce函数实现在./external/selinux/libselinux/src/getenforce.c里面,具体是读取系统节点"sys/fs/selinux/enforce",默认是打开的。


int security_getenforce(void)
{
        int fd, ret, enforce = 0;
        char path[PATH_MAX];
        char buf[20];

        if (!selinux_mnt) {
                errno = ENOENT;
                return -1;
        }

        snprintf(path, sizeof path, "%s/enforce", selinux_mnt);
        fd = open(path, O_RDONLY | O_CLOEXEC);
        if (fd < 0)
                return -1;

        memset(buf, 0, sizeof buf);
        ret = read(fd, buf, sizeof buf - 1);
        close(fd);
        if (ret < 0)
                return -1;

        if (sscanf(buf, "%d", &enforce) != 1)
                return -1;

        return !!enforce;
}

然后如果二者不一致,则将init进程配置的值赋值到kernel对应的节点里面。

external/selinux/libselinux/src/setenforce.c

int security_setenforce(int value)
{
        int fd, ret;
        char path[PATH_MAX];
        char buf[20];

        if (!selinux_mnt) {
                errno = ENOENT;
                return -1;
        }

        snprintf(path, sizeof path, "%s/enforce", selinux_mnt);
        fd = open(path, O_RDWR | O_CLOEXEC);
        if (fd < 0)
                return -1;

        snprintf(buf, sizeof buf, "%d", value);
        ret = write(fd, buf, strlen(buf));
        close(fd);
        if (ret < 0)
                return -1;

        return 0;
}

 

你可能感兴趣的:(【Android】如何配置打开和关闭selinux)