Android 9 SELinux

快速阅读

框架

SELinux介绍

看Android怎么写?

如何确认是SELinux 约束引起?

怎么抓取SELinux Log?

修改之后,怎么快速验证?

怎么从log中提取有效信息?

重点介绍

参考文档



架构

Android 9 SELinux_第1张图片


从上层到驱动层的调用流程,但是我们重点关注sContext:


Android 9 SELinux_第2张图片

注:

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

Android 9 SELinux_第3张图片

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

Android 9 SELinux_第4张图片

注:

1)system/sepolicy/public/te_macros----这是定义方法的地方。eg:init_daemon_domain(adbd)

2)system/sepolicy/Android.mk中有对private、public、vendor目录的说明,具体如下:

Android 9 SELinux_第5张图片

详细说明:

Android 9 SELinux_第6张图片

在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

Android 9 SELinux_第7张图片
Android 9 SELinux_第8张图片

详细介绍:

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

另外,单独编译后,会发现都会有对应的生成目录

Android 9 SELinux_第9张图片

方法二:

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.观察原生:

Android 9 SELinux_第10张图片

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.观察原生:

Android 9 SELinux_第11张图片

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

你可能感兴趣的:(Android 9 SELinux)