美文网首页
selinux 开启关闭

selinux 开启关闭

作者: xuefeng_apple | 来源:发表于2020-05-11 15:02 被阅读0次

    在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 开启关闭

          本文链接:https://www.haomeiwen.com/subject/efpunhtx.html