Android 11源码——安全策略SELinux关闭

Android 11源码 安全策略SELinux关闭

SELinux介绍

作为 Android 安全模型的一部分,Android 使用安全增强型 Linux (SELinux) 对所有进程强制执行强制访问控制 (MAC),甚至包括以 Root/超级用户权限运行的进程(Linux 功能)。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。

SELinux 按照默认拒绝的原则运行:任何未经明确允许的行为都会被拒绝。SELinux 可按两种全局模式运行:

  1. 宽容模式:权限拒绝事件会被记录下来,但不会被强制执行。
  2. 强制模式:权限拒绝事件会被记录下来并强制执行。

Android 中包含 SELinux(处于强制模式)和默认适用于整个 AOSP 的相应安全政策。在强制模式下,非法操作会被阻止,并且尝试进行的所有违规行为都会被内核记录到 dmesg 和 logcat。开发时,您应该先利用这些错误信息对软件和 SELinux 政策进行优化,再对它们进行强制执行。

此外,SELinux 还支持基于域的宽容模式。在这种模式下,可将特定域(进程)设为宽容模式,同时使系统的其余部分处于全局强制模式。简单来说,域是安全政策中用于标识一个进程或一组进程的标签,安全政策会以相同的方式处理所有具有相同域标签的进程。借助基于域的宽容模式,可逐步将 SELinux 应用于系统中越来越多的部分,还可以为新服务制定政策(同时确保系统的其余部分处于强制模式)。

背景

Android 安全模型部分基于应用沙盒的概念。每个应用都在自己的沙盒内运行。在 Android 4.3 之前的版本中,这些沙盒是通过为每个应用创建独一无二的 Linux UID(在应用安装时创建)来定义的。Android 4.3 及更高版本使用 SELinux 进一步定义 Android 应用沙盒的边界。

基于 Android 4.3(宽容模式)和 Android 4.4(部分强制模式),在 Android 5.0 及更高版本中,已全面强制执行 SELinux。通过此项变更,Android 已从对有限的一组关键域(installd、netd、vold 和 zygote)强制执行 SELinux 转为对所有域(超过 60 个)强制执行 SELinux。具体而言:

  • 在 Android 5.x 及更高版本中,所有域均处于强制模式。
  • init 以外的任何进程都不应在 init 域中运行。
  • 出现任何常规拒绝事件(对于 block_device、socket_device、default_service),都表示设备需要一个特殊域。

Android 6.0 通过降低我们政策的宽容度强化了系统安全,从而实现更好的用户隔离和 IOCTL 过滤、降低可从设备/系统之外访问的服务面临的威胁、进一步强化 SELinux 域,以及高度限制对 /proc 的访问。

Android 7.0 更新了 SELinux 配置,以进一步锁定应用沙盒并缩小受攻击面。此版本还将单片式 mediaserver 堆栈拆分为较小的进程,以缩小其权限范围。

Android 8.0 更新了 SELinux 以便与 Treble 配合使用,后者可将较低级别的供应商代码与 Android 系统框架分离开来。此版本更新了 SELinux 政策以允许设备制造商和 SOC 供应商更新自己的政策部分、构建自己的映像(vendor.img、boot.img 等),然后更新这些映像而不受平台影响,反之亦然。

虽然可以在设备上运行更高/更新版本的平台(框架),但反之并不成立;供应商映像 (vendor.img/odm.img) 的版本不能高于平台 (system.img) 的版本。因此,较新版平台可能会带来 SELinux 兼容性问题,因为平台 SELinux 政策的版本要比该政策的供应商 SELinux 部分更新。Android 8.0 模型提供了一种保持兼容性的方法,以免进行不必要的同时 OTA。

关闭Android的SELinux

为什么需要关闭:
由于应用层访问设备节点的时候,因为selinux权限问题而访问不了,所以就先关闭selinux。

查看当前样机的SELinux状态值:

adb shell getenforce

Enforcing:表示SELinux处于开启状态;
Permissive:表示SELinux处于关闭状态。

临时关闭

临时关闭SELinux操作比较简单,但是前提是样机能被root,setenforce 命令修改的是 /sys/fs/selinux/enforce 节点的值,是 kernel 意义上的修改 selinux 的策略。

adb root
adb shell setenforce 0    // 开SELinux:设置成模式permissive    
adb shell setenforce 1    // 关SELinux:设置成模式enforce    
XXX:/ # getenforce   // 获取当前SELinux状态
Enforcing
XXX:/ #  setenforce 0   // 临时关闭SELinux状态
XXX:/ # getenforce   	// 获取SELinux状态
Permissive
XXX:/ # setenforce 1   // 永久开启SELinux状态
XXX:/ # getenforce
Enforcing
XXX:/ #

注意点:

  • 该方式仅适用于 userdebug 版本,系统重启修改会失效
  • root 模式下运行,且必须是终端没有对setenforce进行限制,否则会报如下的错误:
setenforce: Couldn't set enforcing status to '0': Permission denied   //非root情况

永久关闭

init进程是Android内核启动的第一个用户级进程,其中的SELinux也是在init进程中启动的,代码位置在system/core/init/init.cpp中:

main()方法中调用SelinuxInitialize();方法对selinux进行初始化,该方法的实现位于system/core/init/selinux.cpp中:

int main(int argc, char** argv) {
    
    
	...
	SelinuxInitialize();
	...
}

init会通过security_getenforce()和selinux_is_enforcing()的值是否一致来判断是否开启SELinux,当不一致的时候会设置security_setenforce的值为is_enforcing。

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

/selinux.cpp文件中IsEnforcing()方法中直接返回false就是关闭selinux权限了。

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

参考:
https://source.android.google.cn/security/selinux?hl=zh-cn
https://blog.csdn.net/wq892373445/article/details/120823080
https://blog.csdn.net/tkwxty/article/details/103938287?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_paycolumn_v3&utm_relevant_index=5
https://www.jianshu.com/p/f1a6f248c607
https://blog.csdn.net/u012932409/article/details/114632885

猜你喜欢

转载自blog.csdn.net/tracydragonlxy/article/details/124150418