selinux 开启关闭

在init 进程中,初始化调用到了selinux_initialize,这里就决定了selinux 开关
system/core/init/init.cpp

main-->
    selinux_initialize(true);

总结:开启与关闭selinux, 在android 系统中修改ALLOW_PERMISSIVE_SELINUX
system/core/init/Android.mk(Android.bp 也要有对应的修改)

手动操作开启关闭:

echo 0 > /sys/fs/selinux/enforce----> 关闭selinux   (setenforce 0 等价)
echo 1 > /sys/fs/selinux/enforce ----> 开启selinux  (setenforce 1 等价)

下面是具体原理分析:

static void selinux_initialize(bool in_kernel_domain) {
    Timer t;

    selinux_callback cb;
    cb.func_log = selinux_klog_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);
    cb.func_audit = audit_callback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);

    if (in_kernel_domain) {
        LOG(INFO) << "Loading SELinux policy";
        if (!selinux_load_policy()) {
            panic();
        }
        //security_getenforce()----》备注 1:默认配置是 enforce 是1
        bool kernel_enforcing = (security_getenforce() == 1);
        bool is_enforcing = selinux_is_enforcing();-----》 备注 2:由android mk,bp配置 
        if (kernel_enforcing != is_enforcing) {
            if (security_setenforce(is_enforcing)) {----》备注 3:根据返回值is_enforcing 设定
                PLOG(ERROR) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
                security_failure();
            }
        }

        std::string err;
        if (!WriteFile("/sys/fs/selinux/checkreqprot", "0", &err)) {
            LOG(ERROR) << err;
            security_failure();
        }

        // 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);
    } else {
        selinux_init_all_handles();
    }
}

备注 1
external/selinux/libselinux/src/getenforce.c
security_getenforce

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

    if (!selinux_mnt) {
        errno = ENOENT;
        return -1;
    }
        // 这里对应了开发板 android 系统文件是: /sys/fs/selinux/enforce 
    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;   ---->默认是1
}

备注 2

static bool selinux_is_enforcing(void)
{
    if (ALLOW_PERMISSIVE_SELINUX) {
        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
       //selinux_status_from_cmdline --->这里取cmdlines 中参数, boot中不配置可以完全由上层的android mk ,bp文件中的ALLOW_PERMISSIVE_SELINUX 控制开启与关闭
    }
    return true;
}

system/core/init/Android.mk(Android.bp 也要有对应的修改)
ALLOW_PERMISSIVE_SELINUX:

......
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
init_options += \
    -DALLOW_LOCAL_PROP_OVERRIDE=1 \
    -DALLOW_PERMISSIVE_SELINUX=1 \----》userdebug 版本 permissive
    -DREBOOT_BOOTLOADER_ON_PANIC=1 \
    -DDUMP_ON_UMOUNT_FAILURE=0
else
init_options += \
    -DALLOW_LOCAL_PROP_OVERRIDE=0 \
    -DALLOW_PERMISSIVE_SELINUX=1 \----》user 版本 permissive
    -DREBOOT_BOOTLOADER_ON_PANIC=0 \
    -DDUMP_ON_UMOUNT_FAILURE=0
endif
......

备注 3:
实际就操作节点:/sys/fs/selinux/enforce
external/selinux/libselinux/src/setenforce.c
security_setenforce

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;
}

遇到的问题 : 系统开发过程中, userdebug 系统运行正常, 可是在build user 版本系统无法运行,最后发现使用与userdebug 一样的selinux 权限就可以

你可能感兴趣的:(selinux 开启关闭)