SELinux&SEAndroid简介
来源:互联网 发布:mysql if exists用法 编辑:程序博客网 时间:2024/05/21 20:28
这篇文章是替老婆写的公司内部培训PPT。
自从不搞机后,很少研究Android底层架构了,想想我搞智能机的时侯,android4.0 ICS才刚出来。现在已经是Andorid N 7.0了。时光飞逝呀。
文章的主要目的是介绍SELinux及在Android上的规则,让看人看了之后懂得SELinux安全机制是啥样的,并且知道一些常见的问题怎么入手处理。不涉及它的实现。
文章分四部分: SELinux, SEAndroid,Samples, Debug
第一部分 SELinux
1 SELinux是什么
SELinux全称Security-Enhanced Linux
由美国国家安全局NSA 和SCC(Secure Computing Corporation)发起的一个强制访问控制安全模块。在linux kernel 2.6版本后,整合到linux的安全模块中。
SElinux想要解决的是安全问题,简单地说就是,指定的进程只能访问特定的资源,执行特定的操作,而在规定之外的则不能进行操作。从而避免越权的操作,进而达到系统安全。
SELinux提供了一种灵活的强制访问控制(MAC)系统,且内嵌于Linux Kernel中。
2 传统DAC机制
DAC linux 传统的权限管理机制
全称Discretionary Access control, 自主访问控制
基于用户和分组,进程的权限取决于调起这个进程的用户的权限
按照 Owner Group Other 对访问资源的进程的权限进行定义
Root用户具有所有的访问权限
3 SELinux MAC机制
MAC Mandatory Access control, 强制性访问控制
每一项访问, 每访问一个文件资源都需要根据已定义的策略进行针对性的验证
限制Root 权限, 即使你有root 权限, 如果无法通过MAC 验证, 那么一样的无法真正执行相关的操作
对每一项权限进行了更加完整的细化, 可限制用户对资源的访问行为
4 SELinux审查流程
每个系统调用(system call)访问资源时:
先DAC审查,通过后过再进行SELinux的MAC审查
5 SELinux引入的概念
主体(subject)与客体(object)
所有资源可以分为两类: 主体和客体
主体是活的,可以主动对其他资源进行某些操作的,在linux中指进程。
客体则是死的,被动的。除了主体之外的资源(file,socket,device等)。
标签(Labels)
所有subject和object都有自己的标签,比如进程,目录,文件,设备,网终端口,主机名等资源都有自己的标签。
通过编写规则来控制某个subject标签对某个object标签的访问,这就是所谓管理政策。
如下面 u:object_r:system_file:s0 表示 用户,角色,类型,安全级别 , 这些字符串都是标签
-rwxr-xr-x root shell u:object_r:system_file:s0 dexdump
安全上下文(Security Context)
对象都有一个安全上下文(Security Context),它是一串字符串,通示标签构建。
标准格式:user:role:type:mls_level
比如u:object_r:system_file:s0
用户user与角色role
用于角色访问控制,user不是linux uid,是MAC专用的定义,一个user可以属于多个role,不同的role具有不同的权限, android只定义一个用户u和一个subject角色r,一个object角色object_r,即不使用角色访问控制功能,这里不作详述。
安全级别
主体(subject)和客体(object)都关联有一个安全级别,安全级别较高的主体可以读取安全级别较低的客体,而安全级别较低的主体可以写入安全级别较高的客体,通过这种规则,可以允许数据从安全级别较低的主体流向安全级别较高的主体,而限制数据从安全级别较高的主体流向安全级别较低的主体.Android只定义一种安全级别S0,即不使用安全级别。
类型type,域domain,类class
type: 标注资源类型。
domain:和type一样,但是只限于标注subject,即进程的类型。
class:客体(object)的类别,本质上是具有相同操作权限集合的资源类型 , 比如file,它有open,read,write等操作,就定义一个file的class,包含所有相关操作权限。
策略
指定处于什么域的subject可以对什么类型的object执行那些权限的操作.
比如:
allow appdomain app_data_file:file rw_file_perms;
表示 所有应用的域都允许读写标记有app_data_file的文件
6 SELinux审查规则
对象访问系统资源都要进行安全上下文审查,审查规则有:
类型强制检测(type enforcement)
主要的审查机制,根据对像类型和域制定权限策略。
多层安全审查(Multi-Level Security)
android只定义一种权限级别s0,没有启用多层权限。
基于角色的访问控制(RBAC: Role Based Access Control)
android只定一种用户u,没有启用角色控制。
7 类型强制检测(TE)
TE根据Type标签进行安全审查
审查 subject type 对 object type 的某个class 类型中某种permission 是否具有访问权限,是目前使用最为广泛的MAC 审查机制
策略格式:
rule subject_type target_type : class perm_set
rule:控制类型,比如allow neverallow.
subject_type:指domain
target_type:请求资源的类型
class perm_set: 对资源的操作
//init进程 创建/data/property and files
allow init property_data_file:dir create_dir_perms;
allow init property_data_file:file create_file_perms;
8 Type Transitions类型切换
Domain Transitions
一个进程fork 另外一个进程并执行(exec) 一个执行档时,为了避免新进程权限和源进程一样大,需要进行domain 切换
Object Transitions
process创建文件时, 默认是沿用父目录的Security Context, 如果要设置成特定的Label, 就必须进行Object切换。
9 SELinux模式
Permissve Mode(宽容模式)
通过Audit System 记录LOG, 但不真正拦截访问。
Enfocing mode(强制模式)
在打印LOG 的同时,还会真正的拦截访问.
在调试时,我们会启用Permissive Mode, 以便尽可能的发现多的问题, 然后一次修正. 在真正量产时使用Enforcing mode, 来保护系统.
第二部分 SEAndroid
1 SEAndroid是什么
SEAndroid 是将SELinux 移植到Android 上的产物,可以看成SELinux 辅以一套适用于Android 的策略。
特点:
只定义一个用户u和一个subject角色r,一个object角色object_r.
只定义一种权限级别s0
表明SEAndroid的安全策略只用到了类型强制检测,多层安全审查和角色访问控制都没有使用。
2 Android安全机制演变
Android的安全模型是基于应用程序沙箱(sandbox)的概念, 每个应用程序都运行在自己的沙箱之中。
Android 4.3之前:
应用程序安装时为每一个应用程序创建一个独立的uid,基于uid来控制进程权限,即DAC机制。
Android 4.3:
开启SELlinux Permissive 模式
Android 4.4:
对netd, installd, zygote, vold 四个原本具有root 权限的process, 以及它们fork 出的子进程启用Enforce 模式
Android 5.0(L):
普遍性开启SELinux Enforce mode
除了init进程,其他进程都不应该在init 域中
3 SEAndroid策略文件在那里
android rom中的路径:
/sepolicy
/file_contexts
/seapp_contexts
/service_contexts
/property_contexts
/system/etc/security/mac_permissions.xml
/selinux_version
/selinux_network.sh
android源码中路径:
external/sepolicy (通用)
device/mediatek/common/sepolicy/ 设备商定制
4 SEAndorid策略中的一些基本语法
讲解SEAndroid策略文件前,先了解一些基本语法,主要有下面三类
type
class
allow
type
type用于定义资源类型 即把资源类型和属性关联到一起
属性在后面有详细介绍
type type_id [alias alias_id,] [attribute_id]
将type_id(别名为alias)关联到attribute. 这样的话,方便用attribute来管理不同的type中包含相同的属性的部分。
例子:
type init, domain;
将init关联到domain,即将domain设置为init类型的属性
class
用于定义资源类别的权限集合
class class_name [ inherits common_name ] { permission_name … }
inherits表示继承了common定义的权限,然后自己额外实现了permission_name的权限
例子:
class dir inherits file
{
add_name
remove_name
reparent
search
rmdir
open
audit_access
execmod
}
dir继承 file的操作权限集合并增加自己的操作
allow
allow:赋予某项权限。
allowaudit:audit含义就是记录某项操作。默认情况下是SELinux只记录那些权限检查失败的操作
dontaudit:对那些权限检查失败的操作不做记录。
neverallow:用来检查安全策略文件中是否有违反该项规则的allow语句。
例子:
allow init unlabeled:filesystem mount;
允许init类型对unlabeled类型的filesystem进行mount的操作
neverallow { appdomain -unconfineddomain } kmem_device:chr_file { read write };
绝对不允许app(除了有unconfineddomain属性的app)对kmem_device类型的字符设备进行读写的操作
5 SEAndroid策略文件说明
attributes与type
TE安全策略中最基本的参量是type,同时将具有共性的type归在一起构成一个称为attribute的集合。
sepolicy的规则执行也能以attribute作为执行对象
每一个资源对应一个type, 每一个type 对应有一个或几个Attribute.
attrubites定义在external/attrubites:
attribute dev_type;
attribute domain;
attribute fs_type;
Type 的定义就比较分散, 主要有:
普通文件 type 定义在 file.te:
type pipefs, fs_type;
type sockfs, fs_type;
type rootfs, fs_type;
设备文件 type 定义在 device.te
type device, dev_type, fs_type;
type adb_device, dev_type;
type ashmem_device, dev_type, mlstrustedobject;
type audio_device, dev_type;
type binder_device, dev_type, mlstrustedobject;
type camera_device, dev_type;
security_classes:定义了所有的class标签名字。
access_vectors
access_vectors:定义每一个class被允许的操作
file_contexts
ile_contexts:保存系统中所有文件的安全上下文定义
其它文件
roles:只定义了一个role,名字就是r
users:将user与role进行了关联
global_macros:定义一些全局的宏定义
te_macros:定义一些TE策略通用操作的宏
*.te:类型强制规则文件
genfs_contexts:虚拟文件系统的安全上下文设置规则
seapp_contexts :用于app打type标签
service_contexts :系统服务安全上下文
property_contexts :系统属性安全上下文
port_contexts:网络端口安全上下文
7 Google官方SELinux策略限定
维持external/sepolicy 与Google AOSP一致, 尽量不要修改. 特别是不要去除任何的neverallow 语句.
严禁修改untrusted_app.te, 放开untrusted_app 的权限.
系统关键进程启动长时间运行的process, 必须进行domain 切换. 比如netd, installd, vold, zygote 等.
Native thread 严禁使用kernel 标签, 而kernel thread 除init 外, 都应当是kernel 标签.
在user build 中不能存在如su, recovery, init_shell 标签的进程.
在user build 中所有的process 都必须是Enforce Mode
第三部分 Samples
1 mediaserver.te类型审查说明
类型审查, 通常涉及到:
domain 类型定义
执行档 入口定义
SELinux 模式设置
domain 切换
类型访问规则
以mediaserver 这个进程的定义来说明, 对应文件是 mediaserver.te
domain 类型定义
type mediaserver, domain;
执行档 入口定义
type mediaserver_exec, exec_type, file_type;
SELinux 模式设置
在L 版本上,默认都是 enforcing mode
domain 切换
init_daemon_domain(mediaserver)
这个是一个复杂的TE操作宏, 简单来说就是当init fork 子进程执行mediaserver_exec 这个类型的执行档时, 其domain 从init 切换到mediaserver.
允许 mediaserver 访问init 的property socket
unix_socket_connect(mediaserver, property, init)
允许mediaserver 读取sdcard_type 类型的目录和文件
r_dir_file(mediaserver, sdcard_type)
允许mediaserver 使用binder 服务 和发起 binder call.
binder_use(mediaserver)
binder_call(mediaserver, binderservicedomain)
binder_call(mediaserver, appdomain)
binder_service(mediaserver)
允许mediaserver 做其他的一些操作.
allow mediaserver self:process execmem;
allow mediaserver kernel:system module_request;
allow mediaserver media_data_file:dir create_dir_perms;
allow mediaserver media_data_file:file create_file_perms;
allow mediaserver app_data_file:dir search;
allow mediaserver app_data_file:file rw_file_perms;
allow mediaserver sdcard_type:file write;
allow mediaserver gpu_device:chr_file rw_file_perms;
allow mediaserver video_device:dir r_dir_perms;
2 新的service如何添加SELinux策略
假如我们要新增一个init 启动的service,名字叫demo_service, 对应的执行档是/system/bin/demo.
1.创建一个demo.te
/device/mediatke/common/sepolicy 目录下新增demo.te, 在/device/mediatke/common/BoardConfig.mk 的BOARD_SEPOLICY_UNION 宏中新增 demo.te
2 定义demo 类型,init 启动service 时进行类型转换,
在demo.te 中
•type demo, domain;
•type demo_exec, exec_type, file_type;
•init_daemon_domain(demo)
3.绑定执行档 file_contexts 类型
/system/bin/demo u:object_r:demo_exec:s0
4.根据demo 需要访问的文件以及设备, 定义其它的权限在demo.te 中.
第四部分 Debug
1 确认问题是否有SELinux有关
将SELinux 调整到Permissive 模式测试.
将SELinux 模式调整到Permissive 模式,然后再测试确认是否与SELinux 约束相关.
ENG 版本:
adb shell setenforce 0
如果还能复现问题,则与SELinux 无关, 如果原本很容易复现, 而Permissive mode 不能再复现, 那么就可能关系比较大.
查看LOG 中是否有标准的SELinux Policy Exception.
在Kernel LOG / Main Log 中查询关键字 “avc:” 看看是否有SELinux Policy Exception, 并进一步确认这个异常是否与当时的逻辑相关.
2 SELinux Policy Exception LOG解释
SELinux Policy Exception 的LOG 关键字是 “avc: denied” 或者 “avc: denied”, 下面就是一句典型的LOG
<5> type=1400 audit: avc: denied { read write } for pid=177
comm=”rmt_storage” name=”mem” dev=”tmpfs” ino=6004 scontext=u:r:rmt:s0
tcontext=u:object_r:kmem_device:s0 tclass=chr_file
avc: denied { read write } : 拒绝 read write操作
pid=177 comm=”rmt_storage”: pid进程号 comm进程名
scontext=u:r:rmt:s0 : subject context
tcontext=u:object_r:kmem_device:s0 : object context
tclass=chr_file : class类型是chr_file(字符设备文件)
意思是rmt_storeage进程使用rmt的context访问字符设备kmem_device,并进行read write操作时,被SELinux拒绝
3 如何解决avc: denied
上面的例子中,很明显看出原因是在sepolicy 策略语言中,缺乏这样的语句allow rmt kmem_device:chr_file {read write}
所以在/external/sepolicy/ 目录下相应的te文件加入allow rmt kmem_device:chr_file {read write},重编编译,刷机即可。
4 audit2allow工具
当avc很多时,人工去看容易出错且慢,我们可以使用aduit2allow工具来完成这项工作.
audit2allow是policycoreutils中的工具之一,需要在你的linux开发环境中安装。
aduit2allow可以分析log,并自动给出建议的sepolicy语句。
adb shell su -c dmesg | audit2allow
把dmesg log输入到aduit2allow
例如上诉avc语句就会输出:
============= rmt ==============
allow rmt kmem_device:chr_file { read write };
audit2allow只是自动的帮您将LOG 转换成policy, 而无法知道你操作的真实意图,有可能出现权限放大问题,导致被Google默认的neverallow规则拒绝,出现policy 无法编译通过的情况。
最好把audit2allow的输出作为参考,再参考neverallow规则,自己定义sepolicy策略语句。
- SELinux&SEAndroid简介
- Selinux SeAndroid
- 深入理解SELinux/SEAndroid
- 深入理解SELinux/SEAndroid
- 深入理解SELinux/SEAndroid
- 深入理解SELinux SEAndroid
- SELinux/SEAndroid -- 基础知识介绍
- 深入理解SELinux SEAndroid
- Selinux SeAndroid理解
- 深入理解SELinux SEAndroid
- 深入理解SELinux SEAndroid
- 深入理解SELinux SEAndroid
- Selinux SeAndroid理解
- SEAndroid简介
- SEAndroid简介
- SELinux/SEAndroid 实例简述(三)实例看SELinux/SEAndroid
- seandroid对selinux的改进
- 深入理解SELinux SEAndroid(一)
- seetaface 人脸检测库
- 百度统计了解
- Android一点 打造全功能适配AutoView
- 安卓配置问题
- 学习Json小体会
- SELinux&SEAndroid简介
- docker命令自动补全
- 252. Meeting Rooms
- Mybatis的注解应用之关系映射
- JAVA使用http发送post或get请求实例
- Swift 3.0 学习笔记-5-函数
- linux初学 unit2 练习
- 树莓派上安装turtlebot
- nginx源码分析—处理继承的sockets