Android 9 SELinux

快速阅读

框架

SELinux介绍

看Android怎么写?

如何确认是SELinux 约束引起?

怎么抓取SELinux Log?

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

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

如何设置SELinux模式?

重点介绍

参考文档



架构


从上层到驱动层的调用流程,但是我们重点关注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;

如何设置SELinux模式?

两种方案:

方案一:修改system/core/init/Android.mk

ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))

init_options += \

    -DALLOW_LOCAL_PROP_OVERRIDE=1 \

    -DALLOW_PERMISSIVE_SELINUX=1 \

    -DREBOOT_BOOTLOADER_ON_PANIC=1 \

    -DWORLD_WRITABLE_KMSG=1 \

    -DDUMP_ON_UMOUNT_FAILURE=1

else

修改为

ifneq (,$(filter user userdebug eng,$(TARGET_BUILD_VARIANT)))

方案二:直接简单粗暴的修改代码system/core/init/selinux.cpp

bool IsEnforcing() {

return false; //force set selinux permissive.

if (ALLOW_PERMISSIVE_SELINUX) {

return StatusFromCmdline() == SELINUX_ENFORCING;

}

return true;

}

重点介绍

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

https://source.android.com/devices/architecture/configuration/add-system-properties?hl=zh-cn

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 历史 Android的安全模型是基于一部分应用程序沙箱(sandbox)的概念, 每个应用程序都运行在自己的...
    恶魔殿下_HIM阅读 35,034评论 4 24
  • 如果怀疑是sepolicy权限导致的问题,首先需要确认是否真的是权限导致的。 确认方法是:关闭SELinux,查看...
    祝三壮阅读 10,547评论 0 5
  • 深入理解SELinux SEAndroid SEAndroid是Google在Android 4.4上正式推出的一...
    神农修行阅读 7,558评论 1 7
  • 每年四月的第一天,好多人都会在社交平台换上签名“我就是我,不一样的烟火”。除了缅怀哥哥,也是表达了他们自己内心深处...
    漫书V阅读 300评论 0 5
  • python 1.python中数组和矩阵乘法及使用总结 对数组的运算 矩阵求逆,转置,求迹
    逃淘桃阅读 311评论 2 0