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基础知识已经全部完毕,希望能吸引你,激活发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。
来源:CSDN
作者:进阶的凯子
链接:https://blog.csdn.net/tkwxty/article/details/104538447