Android SELinux开发入门指南之SELinux基础知识

我们两清 提交于 2020-02-28 07:02:51

   Android SELinux开发入门指南之SELinux基础知识



前言

   SEAndroid是在Android系统中基于SELinux推出的强制访问控制模型,来完善自主访问模型中只要取得root权限就可以为所欲为的情况。

SELinux是一种基于域-类型(domain-type)模型的强制访问控制(MAC)安全系统,其原则是任何进程想在SELinux系统中干任何事,都必须先在安全策略的配置文件中赋予权限。凡是没有在安全策略中配置的权限,进程就没有该项操作的权限。在SELinux出现之前,Linux的安全模型是DAC(DiscretionaryAccess Control),译为自主访问控制。其核心思想是进程理论上所拥有的权限与运行它的用户权限相同。比如,以root用户启动shell,那么shell就有root用户的权限,在Linux系统上能干任何事。这种管理显然比较松散。在SELinux中,如果需要访问资源,系统会先进行DAC检查,不通过则访问失败,然后再进行MAC权限检查。



一. SELinux基础知识

SELinux涉及的基本知识比较多,下面让我们来一一细说。

1.1 SELinux的三种模式

SELinux分为三种模式,下面我们看看究竟是那三种模式:

  • Disable模式
    此种模式关闭SELinux检测,不进行任何SELinux权限检查,畅通无阻。

  • Permissive模式
    宽容模式,当权限检查不通过时,不决绝资源访问,只打印avc log日志。

  • Enforceing模式
    强制模式,此种模式下权限检查不通过时,拒绝资源访问,并打出avc log,这个是最恨模式。


1.2 查看SELiux状态和关闭SELinux

查看SElinux的状态:
查看SELinux状态比较简单,可以通过命令行查看SELinux状态:

adb  shell getenforce

还有一种就是通过avc log来确认SELinux的状态:
如果是avc log结尾有permissive=1/0的标识,如果permissive=1说明是Permissive模式模式,如果permissive=0则说明是Enforce模式。

关闭SELinux:
关于怎么关闭SELinux可以参考如下的博文正确姿势临时和永久关闭Android的SELinux里面有比较详细的讲解。


1.3 SEAndroid app分类和其他

SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):

  • untrusted_app 第三方app,没有Android平台签名,没有system权限

  • platform_app 有android平台签名,没有system权限

  • system_app 有android平台签名和system权限

  • untrusted_app_25 第三方app,没有Android平台签名,没有system权限,其定义如下This file defines the rules for untrusted apps running with targetSdkVersion <= 25.

从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app按照这个进行排序property_contexts(系统属性)主要描述系统属性相关


1.4 seapp_contexts定义

seapp_contexts定义在system/sepolicy/seapp_contexts数据文件,如下


isSystemServer=true domain=system_server
user=system seinfo=platform domain=system_app type=system_app_data_file
user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
user=nfc seinfo=platform domain=nfc type=nfc_data_file
user=radio seinfo=platform domain=radio type=radio_data_file
user=shared_relro domain=shared_relro
user=shell seinfo=platform domain=shell type=shell_data_file
user=_isolated domain=isolated_app levelFrom=user
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app domain=untrusted_app type=app_data_file levelFrom=user

从上面可以看出,domain和type由user和seinfo两个参数决定。

比如:

user=system seinfo=platform,domain才是system_app

user=_app,可以是untrusted_app或platform_app,如果seinfo=platform,则是platform_app。


1.5 user和seinfo判定方式

首先看user,user可以理解为UID,例如ps -Z结果如下:

u:r:system_app:s0              system    2414  1172  com.android.keychain
u:r:platform_app:s0            u0_a6     2439  1172  com.android.managedprovisioning
u:r:untrusted_app:s0           u0_a8     2460  1172  com.android.onetimeinitializer
u:r:system_app:s0              system    2480  1172  com.android.tv.settings
u:r:untrusted_app:s0           u0_a27    2504  1172  com.android.email
u:r:untrusted_app:s0           u0_a28    2523  1172  com.android.exchange
u:r:untrusted_app:s0           u0_a7     2567  1172  com.android.musicfx

第一列是SContext,第二列是UID,只要UID是system的基本都是system_app,反过来一样。
其他的U0_XXX要么属于platform_app或untrusted_app
seinfo由external\sepolicy\mac_permissions.xml决定,内容如下:

    <!-- Platform dev key in AOSP -->
    <signer signature="@PLATFORM" >
      <seinfo value="platform" />
    </signer>
 
 
    <!-- All other keys -->
 
    <default>
      <seinfo value="default" />
    </default>

即如果签名是platform,seinfo就是platform,其他的比如shared等,seinfo是default。
比如上面ps -Z的结果里面,OneTimeInitializer.apk是untrusted_app,ManagedProvisioning.apk是platform_app。
分别查看这两个app的Android.mk
packages\apps\OneTimeInitializer\Android.mk 没有定义LOCAL_CERTIFICATE,默认是shared
packages\apps\ManagedProvisioning\Android.mk 有定义LOCAL_CERTIFICATE := platform
因为ManagedProvisioning.apk有platform签名,所以seinfo是platform。


1.6 RBAC和constrain

由前文可知,.te文件内部包含各种allow, type等语句,这些都是TEAC(type enforcement access control),属于SELinux MAC中的核心组成部分。
在TEAC之上,SELinux还有一种基于Role的安全策略,也就是RBAC(role based access control)。
e.g.
constrain file write (u1 == u2 and r1 == r2)
这句话表示只有source和targe的user相同,并且role也相同,才允许write file


1.7 小技巧

使用allow和neverallow语句的时候,可以使用下面的一些小技巧来简化命令书写;

  • ”号,表示除了””以外

  • ”-”号,表示去除某项内容

  • ”*”号,表示所有内容


1.8 SELinux 策略构建和客制化

在Android8.0中,SELinux策略分离成平台(platform)和非平台(non-platform)两部分,而平台策略为了给非平台作者导出特定的类型和属性,又分为平台私有(platform private)和平台公有(platform public)部分。

1.8.1.平台公有策略(platform public seoplicy)

平台共有策略全部定义在/system/sepolicy/public下,public下的type和attribute可以被non-platform中的策略所使用,也就是说,设备制造商的sepolicy作者在non-platform下可以对platform public sepolicy的策略进行扩展。

1.8.2.平台私有策略(platform private seoplicy)

与公有策略相反,被声明为私有策略的type或attribute对non-platform的策略作者是不可见的,这里有些费解,我们举例来说,这里以8.0版本的aosp源代码中的/system/sepolicy/private/目录下的atrace.te文件为例;

  • 8.0版本的aosp中的/system/sepolicy/private/file_contexts定义了“/system/bin/atrace u:object_r:atrace_exec:s0”

  • 然后在/system/sepolicy/private/atrace.te中定义atrace相关的规则;
    我们在device/qcom/sepolicy/common目录下新增一个atrace.te文件,并添加规则 “allow atrace sdcardfs:file read;”

  • 当我们make进行编译时会在校验的时候失败,提示我们“device/qcom/sepolicy/common/atrace.te:2:ERROR ‘unknown type atrace’ at token ‘;’ on line 23355”,那么也就是说private策略中的type和attribute对我们是不可见的。

1.8.3.平台私有映射

映射主要针对旧版本的映射,应用比较少,这里不作研究;



结语

修行至此,上述就是本人总结的在实际开发工作中经常使用到的相关SElinux的重点基础知识,希望对各位有所帮组,各位江湖见。



写在最后

  各位读者看官朋友们,Android SELinux开发入门指南之SELinux基础知识已经全部完毕,希望能吸引你,激活发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!