本文章有三个目的:
1.理解SEAndorid的工作原理
2.能够看懂SEAndroid的规则
3.能够自己增添删改其规则(这一条估计大多数人都用不到,所以前两条是主要目的)
SEAndroid 是御好闷SELinux 在Android 上面的一个移植。SELinux 是Linux上系统保护机制,SELinux 全称 Security Enhanced Linux (安全强化 Linux),是MAC (Mandatory Access Control,强制访问控制系统)的一个实现。其目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。Android系统基于Linux实现。针对传统Linux系统,NSA开发了一套安全机制SELinux,用来加强安全性。然而,由于Android系 统有着独特的用户空间运行时,因此SELinux不能完全适用于Android系统。为此,NSA同Google一起针对Android系统,在SELinux基础上开发了 SEAndroid。
Android 4.4首次引入了这一机制,SEAndroid与SELinux最大的不同在于SEAndroid对Android系统中的Binder做来了适配。进入adb shell 之后可以通过getenforce命令来查看其是否应用。root之后可以通过setenforce 0关闭SEAndroid。但是目前好像镇弯关闭了这一功能。
理解SEAndorid的概念不得不提到DAC 和 MAC。
DAC是传统的Linux的访问控制方式,DAC可以对文件、文件夹、共享资源等进行访问控制。 在DAC这种模型中,文件客体的所有者(或者管理员)负责管理访问控制。DAC使用了ACL(Access Control List,访问控制列袜空表)来给非管理者用户提供不同的权限,而root用户对文件系统有完全自由的控制权。
通俗的说就是,小明如果建立的某个文件他就对这个文件拥有绝对的控制权,他能够自主的控制其他人对该文件的权限。一个文件权限有读(r)写(w)执行(x)三种。我们可以通过ls -l 这个命令看到各个文件的权限情况。然后通过 chmod 这个命令可以指定这个其他人对这个文件的权限。(chmod 777 1.txt 这个命令大家应该都明白就不细说了)
但是这个机制有个不好的地方就是root用户可以控制任意文件的权限,可以为所欲为。而且控制粒度较粗,如果我只想让另一个人读我的文件,而这个人跟我不是同一用户组,我只能通过chmod XX4 XX 才能达到这一目的,但是这样的话其他任何人都可以读我的文件。所以说它粒度比较粗。
所以Linux就引入了MAC机制,即强制控制访问。 MAC核心思想 : 即任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。这个机制相当于一个白名单,这个白名单上配置了所有进程的权限,进程只能做白名单上权限内的事情,一旦它想做一个不属于它权限的 *** 作就会被拒绝。
MAC不再像DAC一样简单的把进程分为root others等,而是每个进程(Subject,主体)和文件(Object,客体)都配置了一个类型(Type),当一个进程去 *** 控(读写等)一个文件时,系统会检测该进程类型是否有对该文件类型的 *** 作权限。
通过命令ps -Z 可以查看进程的安全label,ls -Z 可以看到文件的label(安全上下文)。
比如进程安全上下文中的init进程,他的type为init,下面的进程的type为kernel。( 其实进程的type也被称为Domain )
文件安全上下文中的 123.txt 的 type为 tootfs。
(进程和文件安全上下文label格式为 user:role: type :security_level 中的其它几列不用管。这个涉及到SELinux中其它几种访问控制模型,在SEAndroid中我们只用关心他的type就好,比如init进程的 u:r: init: s0,我们只用知道他的type为init。)
知道进程和文件的安全上下文,那具体是怎么通过他们的安全上下文来控制权限的呢?
在手机上有个文件叫做sepolicy,这个文件就是SEAndroid的安全策略配置文件,里面有所有进程的权限配置,进程只能进行它的权限规定内的 *** 作。这个文件就有root权限也删不掉。把这个文件的内容dump出来后会发现里面有好多条规则(我逆过魅族的4000条,三星的20000条)。看两条例子。
allow untrusted_app system_app_data_file : file { read }
allow zygote sdcard_type : file { read write creat rename }
它的具体格式为: allow Domain Type : Class { Permission } (Domain 是指进程的type)
通过这个格式解读上面的三条规则就是,
1. 允许 untrusted_app类型的进程对 system_app_data_file类型的文件进行read。
2.允许zygote类型的进程对sdcard_type的file进行 read write creat rename。
所以MAC控制方式是这个样子的:当一个进程去 *** 作一个文件的时候,系统会去检测这个进程和文件的上下文,看看这个进程的所属的type有没有对这个的文件的type *** 作的权限。比如:zygote如果要去读sdcard上的一个文件,这个文件的type为sdcard,zygote的type(Domain)为zygote, 系统去检测看看发现这条规则 allow zygote sdcard_type : file { read write creat rename }。那么这个 *** 作就会被允许执行。zygote要是想删除一个sdcard上的文件,系统发现对应的规则里没有delete,那么就会被deny。(上面的两条规则和这个例子是我自己编的,只是为了说明情况,真实情况下zygote是有权限删除sdcard上的文件的。)
DAC和MAC是同时作用的,一个 *** 作会先后根据DAC和MAC检测完再去执行,不满足任何一个机制的条件都会被拒绝。
上面一节解释了SEAndroid的工作原理,这下知道为什么zygote的root权限并不能为所欲为了,但是如何去更改SEAndroid的规则,扩大zygote的权限。直接更改sepolicy是不行的,因为sepolicy在boot.img里面,每次开机都会重写读取sepolicy这个文件,无法更改成功。
所以要直接解压boot.img替换里面的sepolicy然后重打包。Linux上有一套解压打包工具,windows解压工具为Android-Image-Tools-windows.zip 先找到手机厂商的官方ROM刷机包,找到boot.img解压。里面有个文件是sepolicy。修改sepolicy然后替换它重新打包刷入手机。(好吧其实蛮复杂的,但是我觉得大多数人可能用不到就先这样写吧,以后有需要的话会详细写。本来打算上传自己工具,不知道怎么上传文件。。。 我找不到我工具的链接了,可以去这里找找))
https://github.com/xmikos/setools-android
1.sepolicy-inject:插入规则
2.sesearch:反编译sepolicy
3.seinfo: 查看sepolicy版本
修改sepolicy的命令:push到手机上 直接输入./(相应文件)即可查看其使用方式 (下面是我插入的其中一条命令)
./sepolicy-inject -s zygote -t labeledfs -c filesystem -p remount,getattr,relabelto,transition,quotamod,unmount -P /sepolicy -o /sdcard/sepolicy1
https://forum.xda-developers.com/showthread.php?t=2073775
博客是学习的起点而不是终点。。。 这篇文章只是入门SEAndroid,目的性较强,只讲了主要部分,很多内容没有涉及。深入了解SEAndroid的话可以去看看老罗的文章。
**最后, 同学点个赞吧!!! 加个关注好么**
参考链接:
SEAndroid安全机制简要介绍和学习计划 强烈推荐老罗
SEAndroid策略分析 推荐
Android的安全机制
深入理解SELinux
你好朋友1. 禁止selinux
1.1 在内核中关闭selinux编译选项CONFIG_SECURITY_SELINUX
1.2 还可以在system.prop中定义ro.boot.selinux=disable
这两种方法都可以禁用selinux,也可以设置成ro.boot.selinux=permissive
宽容模式
1.3 可以通过setenforce 1 开启enforce模式,setenforce 0 为permissive模式
getenforce获取当前模芦老式
2. 所有安全策略最终编译成sepolicy文件放在root目录下,init进程启动后会读取/sepolicy策略文件,并通过/sys/fs/selinux/load节点
把策略文件内容写入内核
3 安全上下文存放root目录
/etc/security/mac_permissions.xml
/file_contexts //系统中所有file_contexts安全上下文
/seapp_contexts //app安全上下文
/property_contexts //属性的安全上下文
/service_contexts//service文件安全上下文
genfs_contexts //虚拟文件系统安全上下文
4. app在/data/data/文件的安全上下文设置过程
1. 根据uid,pkgname,seinfo在seapp_contexts中匹配.
2. 根据匹配到的contexts,重新设置给相对应文件
5. 系统中所有的object class 定义在external/sepolicy/security_classes中.
object class使用在allow语句中,object class所具有的 *** 作定义在external/sepolicy/access_vectors
文件中
6 allow语句缺宽
allow语句用来权限设置
rule_name source_type target_type : class perm_set
rule_name : 有allow,neverallow
source_type : 权限主体,表示source_type对target_type有perm_set描述的权限
如:
allow zygote init:process sigchld
允许zygote域里面的进程可对init域的进程发送sigchld信号
typeattribute表示把属性和type关联起来
7 role定义
Android系统中的role定义在external/sepolicy/roles中,
目前只定义了r
8 socket 使用
以/data/misc/wifi/sockets/wlan0 socket来说明使用方法
1. 定义socket type
type wpa_socket ,file_type
2. 指定安全上下文
/data/misc/wifi/sockets(/.*)? u:object_r:wpa_socket:s0
给/data/misc/wifi/sockets目录下所有的文件统一指定安全上下陪扮升文为wpa_socket
3.声明socket使用权限
在进程te中使用unix_socket_send(clientdomain, wpa, serverdomain)即可建立socket连接
9 binder使用
在使用binder 进程的te中根据情况使用如下宏:
binder_use(domain)//允许domain域中的进程使用binder通信
binder_call(clientdomain, serverdomain) //允许clientdomain和serverdomain域中的进程通信
binder_service(domain) //标志domain为service端
10 文件的使用
以/dev/wmtWifi来说明:
1.定义type
type wmtWifi_device dev_type //dev_type用来标志/dev/下的文件
2.给/dev/wmtWifi指定完全上下文
/dev/wmtWifi(/.*)? u:object_r:wmtWifi_device:s0
3.进程权限设置
在进程te文件中allow权限
allow netd wmtWifi_device:chr_file { write open }
11 property 属性设置
以蓝牙的各种属性来说明
1.定义type
type bluetooth_prop, property_type
2 设置安全上下文
bluetooth. u:object_r:bluetooth_prop:s0
3 进程权限设置
allow bluetooth bluetooth_prop:property_service set
5 专业词汇
MLS :Multi-Level Security
RBAC :Role Based Access Control
DAC :Discretionary Access Control
MAC :Mandatory Access Control
TEAC :Type Enforcement Accesc Control
望采纳祝你好运
[SELinux Policy]如何设置SELinux策略规则?[Description]
android KK 4.4 版本后,Google 默认启用了SELinux, 并会把SELinux 审查异常打印在kernel log
或者 android log(L 版本)中,对应的核森关键字是: "avc: denied" 或者"avc: denied"
如一行LOG:
<5>[ 17.285600].(0)[503:idmap]type=1400 audit(1356999072.320:202): avc: denied { create
} for pid=503 comm="idmap" name="overlays.list" scontext=u:r:zygote:s0
tcontext=ubject_r:resource_cache_data_file:s0 tclass=file
即表明idmap 这个process, 使用zygote 的source context, 访问/data/resource_cache 目录,并
创建文件时,被段春SELinux 拒绝访问。
[Keyword]
android, SELinux, avc: denied, audit
[Solution]
KK 版本, Google 只有限制的启用SELinux, 即只有针对netd, installd, zygote, vold 以及它们
直接fork 出的child process 使用enforcing mode, 但不包括zygote fork的普通app.
L 版本, Google 全面开启SELinux, 几乎所有的process 都使enforcing mode, 影响面非常广.
目前所有的SELinux check 失败,在kernel log 或者android log(L版本后)中都有对应的"avc:
denied" 或者 "avc: denied"的LOG 与之对应。反过来,有此LOG,并非就会直接失败,还需要确认
当时SELinux 的模式, 是enforcing mode 还是 permissve mode.
首先, 务必确认对应进程访问系统资源是否正常, 是否有必要 ?如果本身是异常非法访问,那么
就要自行消除访问。
其次, 如果确认访问是必要,并且正常的,那么就要对对应的process/domain 增加新的policy.
1). 简化方法
1.1 提取所有的avc LOG. 如 adb shell "cat /proc/kmsg | grep avc" >avc_log.txt
1.2 使用 audit2allow tool 直接生成policy. audit2allow -i avc_log.txt 即可自动输出生成的
policy
1.3 将对应的policy 添加到selinux policy 规则中,对应MTK Solution, 您可以将它们添加在KK:
mediatek/custom/common/sepolicy, L: device/mediatek/common/sepolicy 下面,如
allow zygote resource_cache_data_file:dir rw_dir_perms
allow zygote resource_cache_data_file:file create_file_perms
===>mediatek/custom/common/sepolicy/zygote.te (KK)
===>device/mediatek/common/sepolicy/zygote.te (L)
注意audit2allow 它自动机械的帮您将LOG 转换成policy, 而无法知道你 *** 作的真实意图,有可能
出现权限放大问题,经常出现policy 无改燃亩法编译通过的情况。
2). 按需确认方法
此方法需要工程人员对SELinux 基本原理,以及SELinux Policy Language 有了解.
2.1 确认是哪个进程访问哪个资源,具体需要哪些访问权限,read ? write ? exec ? create ?
search ?
2.2 当前进程是否已经创建了policy 文件? 通常是process 的执行档.te,如果没有,并且它的父
进程即source context 无须访问对应的资源,则创建新的te 文件.
在L 版本上, Google 要求维护关键 security context 的唯一性, 比如严禁zygote, netd,
installd, vold, ueventd 等关键process 与其它process 共享同一个security context.
2.3 创建文件后,关联它的执行档,在file_contexts 中, 关联相关的执行档.
比如 /system/bin/idmap 则是 /system/bin/idmap ubject_r:idmap_exec:s0
2.4 填写policy 到相关的te 文件中
如果沿用原来父进程的te 文件,则直接添加.
如果是新的文件,那么首先:
#==============================================
# Type Declaration
#==============================================
type idmap, domain
type idmap_exec, exec_type,file_type
#==============================================
# Android Policy Rule
#==============================================
#permissive idmap
domain_auto_trans(zygote, idmap_exec, idmap)
然后添加新的policy
# new policy
allow idmap resource_cache_data_file:dir rw_dir_perms
allow idmap resource_cache_data_file:file create_file_perms
3). 权限放大情况处理
如果直接按照avc: denied 的LOG 转换出SELinux Policy, 往往会产生权限放大问题. 比如因为要
访问某个device, 在这个device 没有细化SELinux Label 的情况下, 可能出现:
<7>[11281.586780] avc: denied { read write } for pid=1217 comm="mediaserver"
name="tfa9897" dev="tmpfs" ino=4385 scontext=u:r:mediaserver:s0
tcontext=ubject_r:device:s0 tclass=chr_file permissive=0
如果直接按照此LOG 转换出SELinux Policy: allow mediaserver device:chr_file {read write}
那么就会放开mediaserver 读写所有device 的权限. 而Google 为了防止这样的情况, 使用了
neverallow 语句来约束, 这样你编译sepolicy 时就无法编译通过.
为了规避这种权限放大情况, 我们需要细化访问目标(Object) 的SELinux Label, 做到按需申请.
通常会由三步构成
3.1 定义相关的SELinux type.
比如上述案例, 在 device/mediatek/common/sepolicy/device.te 添加
type tfa9897_device, dev_type
3.2 绑定文件与SELinux type.
比如上述案例, 在 device/mediatek/common/sepolicy/file_contexts 添加
/dev/tfa9897(/.*)? ubject_r:tfa9897_device:s0
3.3 添加对应process/domain 的访问权限.
比如上述案例, 在 device/mediatek/common/sepolicy/mediaserver.te 添加
allow mediaserver tfa9897_device:chr_file { open read write }
那么哪些访问对象通常会遇到此类呢?(以L 版本为例)
* device
-- 类型定义: external/sepolicy/device.tedevice/mediatek/common/sepolicy/device.te
-- 类型绑定:
external/sepolicy/file_contextsdevice/mediatek/common/sepolicy/file_contexts
* File 类型:
-- 类型定义: external/sepolicy/file.tedevice/mediatek/common/sepolicy/file.te
-- 绑定类型:
external/sepolicy/file_contextsdevice/mediatek/common/sepolicy/file_contexts
* 虚拟File 类型:
-- 类型定义: external/sepolicy/file.tedevice/mediatek/common/sepolicy/file.te
-- 绑定类型:
external/sepolicy/genfs_contextsdevice/mediatek/common/sepolicy/genfs_contexts
* Service 类型:
-- 类型定义: external/sepolicy/service.tedevice/mediatek/common/sepolicy/service.te
-- 绑定类型
:external/sepolicyservice_contextsdevice/mediatek/common/sepolicy/service_contexts
* Property 类型:
-- 类型定义: external/sepolicy/property.tedevice/mediatek/common/sepolicy/property.te
-- 绑定类型:
external/sepolicy/property_contextsdevice/mediatek/common/sepolicy/property_contexts
通常我们强烈反对更新google default 的policy, 大家可以更新mediatek 下面的相关的policy.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)