Android 9 SELinux
快速阅读
框架
SELinux介绍
看Android怎么写?
如何确认是SELinux 约束引起?
怎么抓取SELinux Log?
修改之后,怎么快速验证?
怎么从log中提取有效信息?
重点介绍
参考文档
架构
从上层到驱动层的调用流程,但是我们重点关注sContext:
注:
file_contexts //系统中所有file_contexts安全上下文
seapp_contexts //app安全上下文
property_contexts //属性的安全上下文
service_contexts //service文件安全上下文
genfs_contexts //虚拟文件系统安全上下文
以上文件system/sepolicy中都有对应的内容
例如:通过adb shell ls –Z指令查看文本的sContext
通过adb shell ps -Z指令可以查看进程的sContext
SELinux介绍
SELinux的背景
1.SELinux则是由美国NSA(国安局)和一些公司(RedHat、Tresys)设计的一个针对Linux的安全加强系统
2.SELinux 按照默认拒绝的原则运行:任何未经明确允许的行为都会被拒绝
3.SELinux的两种模式。
宽容模式:权限拒绝事件会被记录下来,但不会被强制执行。
强制模式:权限拒绝事件会被记录下来并强制执行。
4.Android 4.3(宽容模式)和 Android 4.4(部分强制模式),之后就全面强制执行SELinux
SeLinux作用
提高Android安全性。非法操作会被阻止,并且尝试进行的所有违规行为都会被内核记录到 dmesg 和 logcat 中。例如,app访问文件:/proc/sys/kernel/printk,app设置属性:persist.qiku.log.level等
看Android怎么写?
具体源码路径:
system/sepolicy
注:
1)system/sepolicy/public/te_macros----这是定义方法的地方。eg:init_daemon_domain(adbd)
2)system/sepolicy/Android.mk中有对private、public、vendor目录的说明,具体如下:
详细说明:
在Android8.0以上,SELinux策略分离成平台(platform)和非平台(non-platform)两部分,而平台策略为了给非平台作者导出特定的类型和属性,又分为平台私有(platform private)和平台公有(platform public)部分。
1.平台公有策略(platform public seoplicy)
平台共有策略全部定义在/system/sepolicy/public下,public下的type和attribute可以被non-platform中的策略所使用,也就是说,设备制造商的sepolicy作者在non-platform下可以对platform public sepolicy的策略进行扩展。
2.平台私有策略(platform private seoplicy)
与公有策略相反,被声明为私有策略的type或attribute对non-platform的策略作者是不可见的。
举例,以8.0版本的aosp源代码中的/system/sepolicy/private/目录下的atrace.te文件为例。
1)system/sepolicy/private/file_contexts有定义“/system/bin/atrace u:object_r:atrace_exec:s0”
2)system/sepolicy/private/atrace.te有定义atrace相关的规则
3)我们在device/qcom/sepolicy/common目录下新增一个atrace.te文件,并添加规则 "allow atrace sdcardfs:file read;"
当我们make sepolicy进行编译时会在校验的时候失败,提示我们“device/qcom/sepolicy/common/atrace.te:2:ERROR 'unknown type atrace' at token ';' on line 23355”,那么也就是说private策略中的type和attribute对我们是不可见的。
注:
自我认知说明,scontext只有平台和非平台之分,也就是说,定义在平台private下面file_contexts属性,public和非平台的也可以共享它。
如何确认是Selinux 约束引起?
userdebug版本:
adb root
adb shell setenforce 0
eng版本:
adb shell setenforce 0
详细介绍:
adb shell setenforce 0
0--代表Permissive
1--代表Enforcing
adb shell getenforce---查看状态
如果设置成permissive mode 后问题依旧,说明还有其他的权限问题约束,否则就是SELinux 方面的问题
怎么抓取SELinux Log?
1.adb shell dmesg----抓kernel log
(特别说明:adb shell "cat /proc/kmsg | grep avc" > avc_log.txt 可以直接提出avc的log)
2.adb logcat –b events
关键字:
avc: denied
修改之后,怎么快速验证?
方法一:
mmm system/sepolicy
生成out目录下,注意有两个目录:
system/etc/sepolicy---Android 原生的,建议不动。如果修改,会影响CTS
vendor/etc/sepolicy---第三方厂家修改。
特别说明:
system/sepolicy/Android.mk中定义了一些属性
BOARD_SEPOLICY_DIRS ##此宏涉及到的目录,会编译到vendor/etc/sepolicy下
PLAT_PUBLIC_POLICY ##此宏涉及到的目录,会当成system/sepolicy/public
PLAT_PRIVATE_POLICY##此宏涉及到的目录,会当成system/sepolicy/private
另外,单独编译后,会发现都会有对应的生成目录
方法二:
make sepolicy
怎么从log中提取有效信息?
举例1
<36>[ 103.972283] c0 484 type=1400 audit(1536907169.826:34): avc: denied { read } for pid=2591 comm="roid.qh_engmode" name="printk" dev="proc" ino=35544 scontext=u:r:radio:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=0
普通提取:
allow radio proc:file read;
关键字:
avc: denied { read } scontext=u:r:radio:s0 tcontext=u:object_r:proc:s0 tclass=file
格式:
allow scontext tcontext:tclass {read}
深入提取:
1.观察原生:
2.自建:
1)定义路径
新建文件
genfscon_contexts
输入
genfscon proc /sys/kernel/printk u:object_r:proc_printk:s0
注:proc_printk是自定义的名字
2)定义type
type proc_printk, fs_type, proc_type;
注:
可以新建一个proc_printk.te,或者直接在file.te中导入
3)重新封装
allow radio proc_printk:file read;
目的:
防止与原生中的neverallow发生冲突
举例2
14: 09-03 12:21:04.673 2325 2325 I sh : type=1400 audit(0.0:12): avc: denied { open } for path="/data/misc/qiku" dev="sda35" ino=508404 scontext=u:r:shell:s0 tcontext=u:object_r:system_data_file:s0 tclass=dir permissive=0
普通提取
allow shell system_data_file:dir open;
深入提取
1.观察原生:
2.自建:
1)定义路径
新建文件
file_contexts
输入:
/data/misc/qiku(/.*)? u:object_r:qiku_data_file:s0
2)定义type
type qiku_data_file, file_type, data_file_type;
注:
可以新建一个qiku_data_file.te,或者直接在file.te中导入
3)重新封装
allow shell qiku_data_file:dir open;
重点介绍
1)Android权限必须显示声明,没有声明的话默认就没有权限。
2)neverallow语句的作用
在生成安全策略文件时进行检查,判断是否有违反neverallow语句。也就是说编译过程中,发现neverallow中有注明不能allow的权限,而你又allow了一条,就会编译不过。
参考文档
https://blog.csdn.net/Innost/article/details/19299937
https://blog.csdn.net/Innost/article/details/19641487
https://blog.csdn.net/Innost/article/details/19767621
https://blog.csdn.net/huangyabin001/article/details/79290382
https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials