SELinux机制
1. 自主访问控制与强制访问控制
自主访问控制(DAC):Discretionary Access Control
设计理念:客体(例如文件)的所有者,按照自己的安全策略,授予系统中其他用户对客体的访问权。
Linux中的DAC:进程理论上被授予它的执行者用户的所有权限。比如,以root用户启动Browser,那么Browser就有root用户的权限,在Linux系统上能干任何事。即软件一旦获取root权限,那么该软件也可以为其他软件赋予root权限,从而达到控制系统的目的。
强制访问控制(MAC):Mandatory Access Control
设计理念:系统根据主客体的安全属性,以中心化的强制方式控制主体(进程)对客体(文件)的访问
Linux中的MAC:即任何进程想在SELinux系统中干任何事情,都必须预先在安全策略配置文件中赋予该进程相应的权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。每个进程都有对应的权限声明。
2. SELinux
背景:不希望某个有问题的以root权限运行的程序被攻破后,让整个系统立刻被攻破
SELinux(Security Enhanced Linux)是一个面向Linux内核的强制访问控制(MAC)机制实现。
Android 4.4及之后:
- 对核心系统 daemon:SELinux以强制模式(enforcing mode)运行,违反系统策略将会产生运行时错误,
- 对应用程序:SELinux以宽容模式(permissive mode)运行,违反策略只会被记录进日志,而不会产生运行时错误。
2.1 DAC与SELinux
Android系统是同时支持DAC与SELinux的,
就是说, 在一个进程访问某个资源时,会按照如下规则进行权限控制:
- 首先根据DAC规则, 检查进程权限, 是否具有对应资源的读写/执行权限, 如果没有则拒绝执行
- 如果DAC规则检查通过, 则执行SELinux安全规则的检查, 如果不通过,则拒绝访问
在root安卓手机时,除了进程要切换到root用户身份,还要保证SELinux处于permissive状态,这样才能实现完全的功能(例如,写入某个目录)
2.2 root权限相关的SUID、Capability与SELinux
-
UID机制属于DAC,每个进程维护三个UID标识
其中SUID用于二进制文件对外开放权限,让程序在执行过程中拥有文件拥有者的权限 ,常被用于开放root用户的权限。
SUID机制用于让app进程获得root权限。 -
Capability机制专门针对root权限设计,将root权限细分
实际进行特权操作时,如果euid不是root,便会检查是否具有该特权操作所对应的capabilities,并以此为依据,决定是否可以执行特权操作。
进程的Capability可以从可执行文件的Capability中获得。
一个进程,如果euid不是root,但拥有了所有的Capability,也相当于拥有了root权限。
某些OS中,SUID模式被禁用 (例如安卓4.3之后,/system 和 /data 分区以 nosuid option被挂载),此时: Capability机制用于让app进程获得root权限。我理解,Capability机制也属于DAC,因为进程的Capability由可执行文件决定,而可执行文件的Capability来自root用户的设置,所以也是root用户自主控制的。例如,
sudosetcap cap_net_admin,cap_net_raw+ep /bin/ping
就能给/bin/ping可执行文件添加Capability。 -
SELinux机制属于MAC。
SELinux机制用于对root权限进程的行为进行约束。也就是,即使一个进程的euid是0,或者拥有所有capability, 它也必须受到SELinux策略的约束。
在Android中,基础SELinux策略源码被保存在Android源码树的external/sepolicy/目录下。编译后的策略文件包括一个二进制策略文件和四个配置支持文件:
在Android中,Android 内核在boot阶段启动init时, SELinux通常是宽容模式的。 init会首先加载 /sepolicy二进制策略文件,将SELinux设置为强制模式,然后切换到init进程自己的context,再去启动services/daemons/processes。
这之后,SELinux策略甚至不允许 init 把SELinux恢复到宽容模式。即使 root 用户 也不能修改该策略。
因此,Magisk 将 /init 文件替换为自定义 init,它patch /sepolicy二进制策略文件, 增设 SUPER CONTEXT (u:r:magisk:s0),并定义服务,让服务使用SUPER CONTEXT启动 Magisk daemon。然后执行原来的init继续引导过程。
参考
《SELinux在Android中的应用》
https://sniffer.site/2019/12/07/selinux%E5%9C%A8android%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/#/%E6%A0%87%E7%AD%BE-label-%E4%B8%8E%E7%AD%96%E7%95%A5%E8%A7%84%E5%88%99
Linux安全机制总结
https://he1m4n6a.github.io/2019/08/03/Linux%E5%AE%89%E5%85%A8%E6%9C%BA%E5%88%B6%E6%80%BB%E7%BB%93/
《第七章:访问控制技术原理和应用》
https://blog.csdn.net/xjc2998310890/article/details/112809763