android中SELINUX规则分析和语法简介【转】
本文转载自:https://blog.csdn.net/LoongEmbedded/article/details/62430039
1. SELINUX是可以理解为一种Android上面的安全机制,是有美国国家安全局和一些公司设计的一个针对linux的安全加强系统
我们可以通过配置SELINUX的相关policy,来定制自己的手机的一些权限,比如,我们可以完全让root用户没有任何的权限和user一样
2. 在android里面,有两个类型,一种是文件,一种是进程。
   针对这两种类型,我们可以先来看看他们的不同。
   在android上面,adb shell之后进入手机,ps -Z可以查看当前进程所拥有的selinux的权限。
举例:
- LABEL USER PID PPID NAME
 - u:r:init:s0 root 1 0 /init
 - u:r:kernel:s0 root 2 0 kthreadd
 - ...
 - u:r:kernel:s0 root 258 2 irq/322-HPH_R O
 - u:r:logd:s0 logd 259 1 /system/bin/logd
 - u:r:healthd:s0 root 260 1 /sbin/healthd
 - u:r:lmkd:s0 root 261 1 /system/bin/lmkd
 - u:r:servicemanager:s0 system 262 1 /system/bin/servicemanager
 - u:r:vold:s0 root 263 1 /system/bin/vold
 - u:r:surfaceflinger:s0 system 264 1 /system/bin/surfaceflinger
 - u:r:tctd:s0 root 265 1 /system/bin/tctd
 - u:r:rfs_access:s0 system 268 1 /system/bin/rfs_access
 - u:r:tee:s0 system 271 1 /system/bin/qseecomd
 - u:r:kernel:s0 root 280 2 kworker/3:1H
 - u:r:kernel:s0 root 290 2 kauditd
 - u:r:rmt_storage:s0 nobody 291 1 /system/bin/rmt_storage
 - u:r:shell:s0 shell 292 1 /system/bin/sh
 - u:r:netd:s0 root 295 1 /system/bin/netd
 - u:r:debuggerd:s0 root 296 1 /system/bin/debuggerd
 - u:r:tee:s0 system 297 271 /system/bin/qseecomd
 
在这个例子中,我们可以进行分析。
    在android中,只定义了一个user即为u. 另外,如果是进程的话,都会统一定义为r,如果是文件的话,会被定义为object_r. 第三个是这个进程type,在andorid里面,定义了100多个type.按照目前我的理解,这个是进程所属的>类型。第四个是s0,这个是一个安全的等级。但是暂时还没有接触到配置这个的地方。
另外就是文件,文件想要查看相关SELINUX权限的话,需要去执行ls -Z
- drwxr-x--x root sdcard_r u:object_r:rootfs:s0 storage
 - drwx--x--x root root u:object_r:tmpfs:s0 synthesis
 - dr-xr-xr-x root root u:object_r:sysfs:s0 sys
 - drwxr-xr-x root root u:object_r:system_file:s0 system
 - drwxrwxr-x system tctpersist u:object_r:tct_persist_file:s0 tctpersist
 - lrwxrwxrwx root root u:object_r:rootfs:s0 tombstones -> /data/tombstones
 - -rw-r--r-- root root u:object_r:rootfs:s0 ueventd.qcom.rc
 - -rw-r--r-- root root u:object_r:rootfs:s0 ueventd.rc
 
在这个例子中,结合上面的分析,我们知道了object_r是代表的文件,u是android的唯一的用户,rootfs是这个文件所对应的类型,s0是一个安全的等级限制。
3. 如何配置selinux
   首先,按照Google的官方文档:
   需要linux内核首先是支持selinux的,另外需要android的selinux的配置文件,也就是extern/sepolicy里面的内容。
   然后就是修改BoardConfig.mk
   Google的nexus的sepolicy的支持就放在了device/lge/mako/sepolicy
   首先会包含厂商定制的sepolicy的文件夹:BOARD_SEPOLICY_DIRS
   然后将规则添加到了sepolicy中:BOARD_SEPOLICY_DIRS
这样的话,我们编译出来的image其实就是具有了selinux的功能。
  其实如果没有厂商定制的话,也是会编译到external/sepolicy的,这样的话,就是使用andriod所有默认的sepolicy(It defines the domains and types for the AOSP services and apps common to all devices. )
然后理解了这个之后,我们可以看到其实很多的厂商也是有自己的配置规则在device/***/***/sepolicy下面的.
4. selinux的配置规则:
   首先要了解sepolicy的结构:
   a. App进程 -> mac_permissions.xml
   b. App数据文件 -> seapp_contexts
   c. 系统文件  ->  file_contexts
   d. 系统属性 -> property_contexts
在te文件中,我们一般遇到的语法是这样的:
   rule_name source_type target_type:class perm_set
   解读为: 为source_type设置一个rule_name的规则,规则是对target_type的class 进行 perm_set的操作。
然后是一些特殊的配置文件:
   a. external/sepolicy/attributes -> 所有定义的attributes都在这个文件
   b. external/sepolicy/access_vectors -> 对应了每一个class可以被允许执行的命令
   c. external/sepolicy/roles  -> Android中只定义了一个role,名字就是r,将r和attribute domain关联起来
   d. external/sepolicy/users  -> 其实是将user与roles进行了关联,设置了user的安全级别,s0为最低级是默认的级别,mls_systemHigh是最高的级别
   e. external/sepolicy/security_classes -> 指的是上文命令中的class,个人认为这个class的内容是指在android运行过程中,程序或者系统可能用到的操作的模块
   f. external/sepolicy/te_macros -> 系统定义的宏全在te_macros文件
   g. external/sepolicy/***.te  -> 一些配置的文件,包含了各种运行的规则
另外,selinux有两种工作模式:
    “permissive”:所有操作都被允许(即没有MAC),但是如果有违反权限的话,会记录日志
    “enforcing”:所有操作都会进行权限检查
最后,type的命令如下:
   type type_id [alias alias_id,] [attribute_id]   # 将type_id(别名为alias)关联到attribute. 这样的话,方便用attribute来管理不同的type中包含相同的属性的部分。
class命令的格式为:
   class class_name [ inherits common_name ] { permission_name ... }
   inherits表示继承了common定义的权限,然后自己额外实现了permission_name的权限
在te文件中常见的四种命名的规则:
   allow:赋予某项权限。
   allowaudit:audit含义就是记录某项操作。默认情况下是SELinux只记录那些权限检查失败的操作。allowaudit则使得权限检查成功的操作也被记录。注意,allowaudit只是允许记录,它和赋予权限没关系。赋予权限必须且只能使
用allow语句。
   dontaudit:对那些权限检查失败的操作不做记录。
   neverallow:前面讲过,用来检查安全策略文件中是否有违反该项规则的allow语句。如例子5所示:
举例:
- type init, domain;
 
将init关联到domain,即将domain设置为init类型的属性
- allow init unlabeled:filesystem mount;
 
允许init类型对unlabeled类型的filesystem进行mount的操作
- allow init fotad:unix_stream_socket { bind create };
 
允许init类型对fotad类型的unix_stream_socket 进行bind和create的操作
- allow appdomain anr_data_file:dir search;
 - allow appdomain anr_data_file:file { open append };
 
首先appdomain是定义在te_macros里面的一个宏,很多的app规则会使用类似app_domain(shell)的命令将其添加进去
   这两句话的意思是:1. 允许app去对anr_data_file类型的目录进行查找的操作
   2. 允许app对anr_data_file类型的file进行打开和添加操作   其实就是规定了出现anr时候,app往/data/anr/里面写入的权限限制
- neverallow { appdomain -unconfineddomain } kmem_device:chr_file { read write };
 
绝对不允许app(除了有unconfineddomain属性的app)对kmem_device类型的字符设备进行读写的操作
- neverallow { appdomain -unconfineddomain } self:capability2 *;
 
绝对不允许除了unconfineddomain以外的app对self类型的capability2进行任何的操作
- type httpd_user_content_t, file_type, httpdcontent;
 
声明一个httpd_user_content_t的类型,具有file_type和httpdcontent的属性
- type httpd_user_content_t;
 - typeattribute httpd_user_content_t file_type, httpdcontent;
 
声明一个httpd_user_content_t的类型
   定义httpd_user_content_t具有file_type, httpdcontent的属性
- allow appdomain self:rawip_socket create_socket_perms;
 
所有可以设置类型的地方其实都可以设置为属性。
   比如这个例子,我们允许所有具有app属性的内容可以去对self属性的rawip_socket进行create的操作
- allow {user_t domain} {bin_t file_type sbin_t}:file execute ;
 
允许user_t和domain属性的类对bin_t, file_type, sbin_t类型的file进行可执行的操作
- allow user_t user_t:process signal;
 - allow user_t self:process signal;
 
这两条语句的表述其实是一致的,其实self指的是目标的类型和发起人的类型是一致的
   所以不能声明一个类型或者属性叫做self
- allow user_t bin_t:file ~{ write setattr ioctl };
 
允许user_t对bin_t类型的file进行除了write setattr ioctl相关的操作
- type_transition system wifi_data_file:sock_file system_wpa_socket;
 
当一个类型为system的类别去进行wifi_data_file类型的sock_file访问时,类型默认切换到system_wpa_socket
如果下面这条语句想要执行成功
   type_transition init_t apache_exec_t:process apache_t;
   至少首先声明下面的三条规则:
   allow init_t apache_exec_t:file execute;
   allow init_t apache_t:process transition;
   allow apache_t apache_exec_t:file entrypoint;
type_transition和type_change的语法规则是一样的, type_change规则的影响不会在内核中生效,而是依赖于用户空间应用程序,如login或sshd
5. 生成方法:
下面介绍一下最简单的安全策略(se-policy)添加方法,各组碰到SELinux导致的访问禁止问题,可以参考用这种方法确认和解决。
1) 安装pc上的工具,用于自动生成安全策略
$ sudo apt-get install policycoreutils
2),刷userdebug/eng软件,先将SELinux设置成Permissive模式,只输出警告不阻止操作
使用getenforce命令查看当前模式:$ adb shell getenforce
Enforcing
在Enforcing模式下,除安全策略允许外的操作都会被阻止;使用setenforce命令更改当前模式(root权限需要):
$ adb root
restarting adbd as root
$ adb shell setenforce 0
$ adb shell getenforce
Permissive
开发如果碰到怀疑是SELinux 可以通过这种方法关闭SELiunx( setenforce 0),以确认是不是SELinux引起的
3),按照流程完成整个操作,抓取log,过滤出警告信息
- 如果log较多,可以先用grep工具过滤一下:
 
$ grep "avc: *denied" log.txt > denied.txt
$ cat denied.txt
<14>[  389.521062] avc:  denied  { set } for property=audio.ftm.rcv_reverse scontext=u:r:system_app:s0 tcontext=u:object_r:default_prop:s0 tclass=property_servic
4),使用pc工具生成安全策略
- 命令audit2allow用来一次性生成所有安全策略,输入为前面抓取的 log
 
$ audit2allow -i denied.txt
android中SELINUX规则分析和语法简介【转】的更多相关文章
- android中SELINUX规则分析和语法简介
		
1. SELINUX是可以理解为一种android上面的安全机制,是有美国国家安全局和一些公司设计的一个针对linux的安全加强系统我们可以通过配置SELINUX的相关policy,来定制自己的手机的 ...
 - Android中AppWidget的分析与应用:AppWidgetProvider .
		
from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...
 - Android 中图片压缩分析(上)
		
作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...
 - Android中SELinux的TE简介【转】
		
转自:https://blog.csdn.net/murphykwu/article/details/52457667 selinux的概念如上一篇链接所示: http://www.cnblogs.c ...
 - Android中Touch事件分析--解决HorizontalScrollView滑动和按钮事件触发问题
		
之前写过关于HorizontalScrollView滑动和按钮事件触发问题,但是不能所有的情况,最近几天一直在想这个问题,今天有一个比较好的解决思路,最终应用在项目里面效果也很好,首先说明一下功能: ...
 - Android中Parcel的分析以及使用
		
简单点来说:Parcel就是一个存放读取数据的容器, Android系统中的binder进程间通信(IPC)就使用了Parcel类来进行客户端与服务端数据的交互,而且AIDL的数据也是通过Parcel ...
 - Android中应用安装分析
		
#1 安装方式 1 安装系统APK和预制APK时,通过PMS的构造函数中安装,即第一次开机时安装应用,没有安装界面. 2 网络下载安装,通过应用商店等,即调用PackageManager.instal ...
 - Android中Context样式分析
		
目录 1.样式定义以及使用 1.1.默认样式 1.2.样式定义及使用 1.3.当前样式下attr属性的获取 1.4.属性集合的定义与获取 2.Activity中Theme的初始化流程 2.1.系统调用 ...
 - android 中theme和style的语法相关
		
1.theme和style都是一组属性的集合,用于定义文本.颜色.大小等显示风格.他们都是资源,可以用android系统级别的一些默认的风格和主题资源,你也可以自定义你自己的主题和风格资源. 2.自定 ...
 
随机推荐
- 使用redis接管session
			
class RedisSession { // 默认配置名称(使用load_config加载) private $_default_config_path = 'package/cache/redis ...
 - yarn集群客户端gateway常用限制
			
spark默认集群模式,省略上传依赖包过程:spark-default.sh spark.yarn.jars hdfs:///${PATH}/sparkJar/jars/*.jarspark.subm ...
 - JavaScript 里,$ 代表什么?/JQuery是什么语言?/html中用link标签引入css时的中 rel="stylesheet"属性?/EL表达式是什么?
			
JavaScript 里,$ 代表什么? 比如说我写一个mouseover事件: $(document).ready(function(){ $("p").mouseover(fu ...
 - juqery 回车事件  回车操作   回车搜索
			
html <form class="search_wrap" method="post" action=""> <div ...
 - Linux 下挂载新硬盘方法
			
Linux的硬盘识别: 一般使用”fdisk -l”命令可以列出系统中当前连接的硬盘 设备和分区信息.新硬盘没有分区信息,则只显示硬盘大小信息. 1.关闭服务器加上新硬盘 2.启动服务器,以r ...
 - C++的一些知识
			
1.C++中非虚函数都是静态绑定,虚函数是动态绑定.指针或引用访问对象的虚函数时才能进行动态绑定. 静态多态性:编译时确定操作的对象.如:函数重载,运算符重载. 动态多态性:运行时确定操作的对象. 绑 ...
 - [No0000198]swagger api一键导入postman
			
在用postman进行接口测试时,对于参数较多的接口时第一次添加接口参数是比较繁琐的,可利用swagger一键导入api接口,事例如下: 1.获取swagger地址 2.打开postman,点击imp ...
 - arcpy加载mxd文件时,无效的MXD路径,提示assert (os.path.isfile(mxd) or (mxd.lower() == "current")), gp.getIDMessage(89004, "Invalid MXD filename")
			
无效的MXD路径,将路径前加‘u’,改为这种: mxdPath = u"C:\\1331\\DB\\Original Files\\dd.mxd" 参考: https://gis. ...
 - HashMap出现Hash DOS攻击的问题
			
随着RESTful风格的接口普及,程序员默认都会使用json作为数据传递的方式.json格式的数据冗余少,兼容性高,从提出到现在已被广泛的使用,可以说成为了Web的一种标准.无论我们服务端使用什么语言 ...
 - Spark入门到精通--(第一节)Spark的前世今生
			
最近由于公司慢慢往spark方面开始转型,本人也开始学习,今后陆续会更新一些spark学习的新的体会,希望能够和大家一起分享和进步. Spark是什么? Apache Spark™ is a fast ...