SELinux/SEAndroid 实例简述(二) TE语言规则
2017-03-07 16:11
513 查看
一.基本语法
很多te文件集中在\external\sepolicy文件夹下,MTK也有很多自定义的在\device\mediatek\common\sepolicy。它的最基本样式是
这些allow语句就是最基本的te语句了,相似的te语句的会被归类在一个的te文件下面。如上面的语句是作用于factory,则会在factory.te文件里。\external\sepolicy集中了很多系统定义的te文件
最基本的语法为:
我们 从上面拿一个实例下来分析一下:
file_contexts里面显式定义了哪些文件属于ttyMT_device类型的
te表达式基本上就是这样:
rule_name:规则名称,除了有allow还有dontaudit,auditallow和neverallow
source_type:源类型,对应一个很重要的概念--------域(domain)
tartget_type:目标的类型,SELinux一个重要的判断对象
class:类别,目标(客体)是哪种类别,主要有File,Dir,Socket,SEAndroid还有Binder等,在这些基础上又细分出设备字符类型(chr_file),链接文件(lnk_file)等。可以通过ls-l查看文件类型
perm_set:动作集
从上到下按顺序介绍一下:
rule_name:
allow:允许某个进程执行某个动作
auditallow:audit含义就是记录某项操作。默认SELinux只记录那些权限检查失败的操作。auditallow则使得权限检查成功的操作也被记录。注意,allowaudit只是允许记录,它和赋予权限没关系。赋予权限必须且只能使用allow语句。
dontaudit:对那些权限检查失败的操作不做记录。
neverallow:没有被allow到的动作默认就不允许执行的。neverallow只是显式地写出某个动作不被允许,如果添加了该动作的allow,则会编译错误
source_type:
指定一个“域”(domain),一般用于描述进程,该域内的的进程,受该条TE语句的限制。用type关键字,把一个自定义的域与原有的域相关联
最简单地定义一个新域的方式为:
上面这句话的意思是,赋予shell给domain属性,同时,shell与属于domain这个集合里。如果有一个allowdomainxxxxx的语句,同样地也给了shellxxxxx的属性
target_type:
指定进程需要操作的客体(文件,文件夹等)类型,同样是用type与一些已有的类型,属性相关联
以上面的ttyMT_device为例:
attribute关键字定义一个属性,type可以与一个或多个属性关联,如
另外,还有一个关键字typeattribute,type有两个作用,定义(声明)并关联某个属性。可以把这两个作用分开,type定义,typeattribute进行关联
然后你会有一个疑问,这么多属性,这些属性有什么作用,这些属性会有一个地方显式地说明这个属性拥有什么权限,在external/sepolicy/domain里就有非常详细的描述。另个在external/sepolicy/attributes里定义了很多属性,下面截取了一些常见的定义
class:
客体的具体类别。用class来定义一个客体类别,具体定义方式如下
perm_set:
具体的操作,系统的定义在external/sepolicy/access_vectors。有两种定义方法。
用common命令定义:
用class命令定义:
----------------引用于《android中SELINUX规则分析和语法简介》
二.TE的正则表达式和集合
TE文件支持正则表达式,从下面可以看到,通配符是常用的通配符,可以度娘
需要注意的是上面的"--",这里的“--”表示二进制文件,类似的还有
TE表达式里可以用“{}”来表示一个集合,如:
可以在集合里使用“*”,“-”和“~”三个通配符
三.TE的类型转换规则
为什么要转换类型
init进程拥有系统的最高权限,如果由Init进程fork,execu出来的进程默认是与init相同的权限,这肯定是不安全的。另一个场景是,由init生成的文件,默认也是init的读写权限,不方便其他低权限的文件进行访问。
类型转换有两种类型转换:
1.主体的域的转换
2.客体的转换
域的转换
type_transition的完整格式为:
type_transitioninit_tapache_exec_t:processapache_t;
init_t进程执行type为apache_exec_t的可执行文件时,新的进程转换到apache_t域
但是上面只是告诉了转换的过程,却没有说明,有转换的权限,如果要上面的转换成功,还需要下面的语句:
客体的转换
例子:
passwd_t在tmp_t目录下创建文件时,该文件的类型转化为passwd_tmp_t。这里默认隐含了一个tmp_t类型dir,因为file的容器只能是个dir。同样的,如果要上面的语句运行成功,与需要有相应的权限说明:
如果每个转换之前都需要这样繁锁地权限声音实在很麻烦。TE里允许把这些相同的,重复使用的语句定义成一个宏,类似于函数一样。
四.TE的宏
如果把上面domain转换的例子定义成一个宏,应该定义如下:
上面的宏定义在external/sepolicy/te_macros里。客体的转换定义如下:
TE的集合也可以定义成一个宏代替,如读写文件操作集的宏:
使用方式是:
参考文章:
http://blog.csdn.net/Innost/article/details/19299937?locationNum=2
系列文章
http://www.2cto.com/kf/201504/390742.html
http://blog.csdn.net/luoshengyang/article/details/35392905 系列文章
http://blog.csdn.net/myarrow/article/details/10105961
很多te文件集中在\external\sepolicy文件夹下,MTK也有很多自定义的在\device\mediatek\common\sepolicy。它的最基本样式是
allowfactorypowerctl_prop:property_serviceset;
allowfactoryttyGS_device:chr_file{readwriteopenioctl};
allowfactoryttyMT_device:chr_file{readwriteopenioctl};
allowfactoryirtx_device:chr_file{readwriteioctlopen};
allowfactorydevpts:chr_file{readwritegetattrioctl};
这些allow语句就是最基本的te语句了,相似的te语句的会被归类在一个的te文件下面。如上面的语句是作用于factory,则会在factory.te文件里。\external\sepolicy集中了很多系统定义的te文件
文件名 | 归类 |
mac_permissions.xml | App进程 |
seapp_contexts | App数据文件 |
file_contexts | 系统文件 |
property_contexts | 系统属性 |
/*
rule_name:规则名,分别有allow,dontaudit,neverallow等
source_type:主要作用是用来填写一个域(domain)
target_type:类型
class:类别,主要有File,Dir,Socket,SEAndroid还有Binder等
perm_set:动作集
*/
rule_namesource_typetarget_type:classperm_set
我们 从上面拿一个实例下来分析一下:
/*
用中文来表述是:允许factory域里的进程或服务
对类型为ttyMT_device的类别为文件(file)
执行open,read,write,ioctl权限
*/
allowfactoryttyMT_device:chr_file{readwriteopenioctl};
file_contexts里面显式定义了哪些文件属于ttyMT_device类型的
/dev/ttyMT.*u:object_r:ttyMT_device:s0
te表达式基本上就是这样:
rule_name:规则名称,除了有allow还有dontaudit,auditallow和neverallow
source_type:源类型,对应一个很重要的概念--------域(domain)
tartget_type:目标的类型,SELinux一个重要的判断对象
class:类别,目标(客体)是哪种类别,主要有File,Dir,Socket,SEAndroid还有Binder等,在这些基础上又细分出设备字符类型(chr_file),链接文件(lnk_file)等。可以通过ls-l查看文件类型
perm_set:动作集
从上到下按顺序介绍一下:
rule_name:
allow:允许某个进程执行某个动作
auditallow:audit含义就是记录某项操作。默认SELinux只记录那些权限检查失败的操作。auditallow则使得权限检查成功的操作也被记录。注意,allowaudit只是允许记录,它和赋予权限没关系。赋予权限必须且只能使用allow语句。
dontaudit:对那些权限检查失败的操作不做记录。
neverallow:没有被allow到的动作默认就不允许执行的。neverallow只是显式地写出某个动作不被允许,如果添加了该动作的allow,则会编译错误
source_type:
指定一个“域”(domain),一般用于描述进程,该域内的的进程,受该条TE语句的限制。用type关键字,把一个自定义的域与原有的域相关联
最简单地定义一个新域的方式为:
typeshell,domain
上面这句话的意思是,赋予shell给domain属性,同时,shell与属于domain这个集合里。如果有一个allowdomainxxxxx的语句,同样地也给了shellxxxxx的属性
target_type:
指定进程需要操作的客体(文件,文件夹等)类型,同样是用type与一些已有的类型,属性相关联
以上面的ttyMT_device为例:
//定义一个类型,属于dev_type属性
typettyMT_device,dev_type;
//属性dev_type在external/sepolicyattributes的定义如下
attributedev_type;
attribute关键字定义一个属性,type可以与一个或多个属性关联,如
typeusb_device,dev_type,mlstrustedobject;
另外,还有一个关键字typeattribute,type有两个作用,定义(声明)并关联某个属性。可以把这两个作用分开,type定义,typeattribute进行关联
#定义httpd_user_content_t,并关联两个属性
typehttpd_user_content_t,file_type,httpdcontent;
分成两条语句进行表述:
#定义httpd_user_content_t
typehttpd_user_content_t;
#关联属性
typeattributehttpd_user_content_tfile_type,httpdcontent;
然后你会有一个疑问,这么多属性,这些属性有什么作用,这些属性会有一个地方显式地说明这个属性拥有什么权限,在external/sepolicy/domain里就有非常详细的描述。另个在external/sepolicy/attributes里定义了很多属性,下面截取了一些常见的定义
#Alltypesusedfordevices.
attributedev_type;
#Alltypesusedforprocesses.
attributedomain;
#Alltypesusedforfilesystems.
attributefs_type;
#Alltypesusedforfilesthatcanexistonalabeledfs.
#Donotuseforpseudofiletypes.
attributefile_type;
#Alltypesusedfordomainentrypoints.
attributeexec_type;
#Alltypesusedforpropertyservice
attributeproperty_type;
#Allservice_managertypescreatedbysystem_server
attributesystem_server_service;
#AlldomainsthatcanoverrideMLSrestrictions.
#i.e.processesthatcanreadupandwritedown.
attributemlstrustedsubject;
#AlltypesthatcanoverrideMLSrestrictions.
#i.e.filesthatcanbereadbylowerandwrittenbyhigher
attributemlstrustedobject;
#Alldomainsusedforapps.
attributeappdomain;
#Alldomainsusedforappswithnetworkaccess.
attributenetdomain;
#Alldomainsusedforbinderservicedomains.
attributebinderservicedomain;
class:
客体的具体类别。用class来定义一个客体类别,具体定义方式如下
[external/sepolicy/security_classes示例]
#file-relatedclasses
classfilesystem
classfile#代表普通文件
classdir#代表目录
classfd#代表文件描述符
classlnk_file#代表链接文件
classchr_file#代表字符设备文件
......
#network-relatedclasses
classsocket#socket
classtcp_socket
classudp_socket
......
classbinder#Android平台特有的binder
classzygote#Android平台特有的zygote
perm_set:
具体的操作,系统的定义在external/sepolicy/access_vectors。有两种定义方法。
用common命令定义:
格式为:commoncommon_name{permission_name...}
common定义的permset能被另外一种permset命令class所继承
如:
commonfile{
ioctlreadwritecreategetattrsetattrlockrelabelfromrelabelto
appendunlinklinkrenameexecuteswaponquotaonmounton
用class命令定义:
classclass_name[inheritscommon_name]{permission_name...}
inherits表示继承了某个common定义的权限
注意,class命令它不能被其他class继承
继承一个common,如继承了filecommon
classdir
inheritsfile
{
add_name
remove_name
reparent
search
rmdir
open
audit_access
execmod
}
不继承任何common,如
classbinder
{
impersonate
call
set_context_mgr
transfer
}
然后是一些特殊的配置文件:
a.external/sepolicy/attributes->所有定义的attributes都在这个文件
b.external/sepolicy/access_vectors->对应了每一个class可以被允许执行的命令
c.external/sepolicy/roles->Android中只定义了一个role,名字就是r,将r和attributedomain关联起来
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->一些配置的文件,包含了各种运行的规则
----------------引用于《android中SELINUX规则分析和语法简介》
二.TE的正则表达式和集合
TE文件支持正则表达式,从下面可以看到,通配符是常用的通配符,可以度娘
/sys/devices/system/cpu(/.*)?u:object_r:sysfs_devices_system_cpu:s0
/sys/power/wake_lock--u:object_r:sysfs_wake_lock:s0
/sys/power/wake_unlock--u:object_r:sysfs_wake_lock:s0
/sys/kernel/uevent_helper--u:object_r:usermodehelper:s0
/sys/module/lowmemorykiller(/.*)?--u:object_r:sysfs_lowmemorykiller:s0
#############################
#aseccontainers
/mnt/asec(/.*)?u:object_r:asec_apk_file:s0
/mnt/asec/[^/]+/[^/]+\.zipu:object_r:asec_public_file:s0
需要注意的是上面的"--",这里的“--”表示二进制文件,类似的还有
#‘-b’-BlockDevice‘-c’-CharacterDevice
#‘-d’-Directory‘-p’-NamedPipe
#‘-l’-SymbolicLink‘-s’-Socket
#‘--’-Ordinaryfile
TE表达式里可以用“{}”来表示一个集合,如:
/*
允许user_t对bin_t类型的文件和文件夹执行read,getattr操作
*/
allowuser_tbin_t:{filedir}{readgetattr};
/*
允许domain对exec_type,sbin_t类型的文件执行execute的动作
*/
allowdomain{exec_typesbin_t}:fileexecute;
可以在集合里使用“*”,“-”和“~”三个通配符
/*
允许user_t对bin_t类型的文件和文件夹执行所有操作
*/
allowuser_tbin_t:{filedir}*;
/*
允许user_t对bin_t类型的文件和文件夹执行除了read,getattr以外的所有操作
*/
allowuser_tbin_t:{filedir}~{readgetattr};
/*
允许domain对exec_type类型的文件执行execute的动作,除了sbin_t以外
*/
allowdomain{exec_type-sbin_t}:fileexecute;
三.TE的类型转换规则
为什么要转换类型
init进程拥有系统的最高权限,如果由Init进程fork,execu出来的进程默认是与init相同的权限,这肯定是不安全的。另一个场景是,由init生成的文件,默认也是init的读写权限,不方便其他低权限的文件进行访问。
类型转换有两种类型转换:
1.主体的域的转换
2.客体的转换
域的转换
type_transition的完整格式为:
type_transitionsource_typetarget_type:classdefault_type;
举个例子
type_transitioninit_tapache_exec_t:processapache_t;
type_transitioninit_tapache_exec_t:processapache_t;
init_t进程执行type为apache_exec_t的可执行文件时,新的进程转换到apache_t域
但是上面只是告诉了转换的过程,却没有说明,有转换的权限,如果要上面的转换成功,还需要下面的语句:
#首先,你得让init_t域中的进程能够执行type为apache_exec_t的文件
allowinit_tapache_exec_t:fileexecute;
#然后,你还得告诉SELiux,允许init_t做DT切换以进入apache_t域
allowinit_tapache_t:processtransition;
#最后,你还得告诉SELinux,切换入口(对应为entrypoint权限)为执行pache_exec_t类型的文件
allowapache_tapache_exec_t:fileentrypoint;
客体的转换
例子:
type_transitionpasswd_ttmp_t:filepasswd_tmp_t;
passwd_t在tmp_t目录下创建文件时,该文件的类型转化为passwd_tmp_t。这里默认隐含了一个tmp_t类型dir,因为file的容器只能是个dir。同样的,如果要上面的语句运行成功,与需要有相应的权限说明:
对应的必须有两个前提条件:
*Thesourcedomainneedspermissiontoaddfileentriesintothedirectory
这个process必须有在这个目录下添加文件的权限.
*Thesourcedomainneedspermissiontocreatefileentries
这个process必须有在这个目录下创建以这个SecurityContext为Label的文件权限.
如果每个转换之前都需要这样繁锁地权限声音实在很麻烦。TE里允许把这些相同的,重复使用的语句定义成一个宏,类似于函数一样。
四.TE的宏
如果把上面domain转换的例子定义成一个宏,应该定义如下:
#定义domain_auto_trans宏,$1,$2等等代表宏的第一个,第二个....参数
define(`domain_auto_trans',`
#先allow相关权限,domain_trans宏定义在后面
domain_trans($1,$2,$3)
#然后设置type_transition
type_transition$1$2:process$3;
')
#定义domain_trans宏。
define(`domain_trans',`
#SEAndroid在上述三个最小权限上,还添加了自己的一些权限
allow$1$2:file{getattropenreadexecute};
allow$1$3:processtransition;
allow$3$2:file{entrypointreadexecute};
allow$3$1:processsigchld;
dontaudit$1$3:processnoatsecure;
allow$1$3:process{siginhrlimitinh};
')
上面的宏定义在external/sepolicy/te_macros里。客体的转换定义如下:
#####################################
#file_type_auto_trans(domain,dir_type,file_type)
#Automaticallylabelnewfileswithfile_typewhen
#theyarecreatedbydomainindirectorieslabeleddir_type.
#
define(`file_type_auto_trans',`
#Allowthenecessarypermissions.
file_type_trans($1,$2,$3)
#Makethetransitionoccurbydefault.
type_transition$1$2:dir$3;
type_transition$1$2:notdevfile_class_set$3;
')
define(`file_type_trans',`
#Allowthedomaintoaddentriestothedirectory.
allow$1$2:dirra_dir_perms;
#Allowthedomaintocreatethefile.
allow$1$3:notdevfile_class_setcreate_file_perms;
allow$1$3:dircreate_dir_perms;
')
TE的集合也可以定义成一个宏代替,如读写文件操作集的宏:
define(`x_file_perms',`{getattrexecuteexecute_no_trans}')
define(`r_file_perms',`{getattropenreadioctllock}')
define(`w_file_perms',`{openappendwrite}')
define(`rx_file_perms',`{r_file_permsx_file_perms}')
define(`ra_file_perms',`{r_file_permsappend}')
define(`rw_file_perms',`{r_file_permsw_file_perms}')
define(`rwx_file_perms',`{rw_file_permsx_file_perms}')
define(`create_file_perms',`{createrenamesetattrunlinkrw_file_perms}')
使用方式是:
allowdemodemo_device:chr_filerw_file_perms;
参考文章:
系列文章
相关文章推荐
- SELinux/SEAndroid 实例简述(二) TE语言规则
- SELinux/SEAndroid 实例简述(一) 基础概念
- SELinux/SEAndroid 实例简述(一) 基础概念
- SELinux/SEAndroid 实例简述(三)实例看SELinux/SEAndroid
- 深入理解SELinux SEAndroid(最后部分)
- Make ADB To Support Android Devices(如何使ADB在Linux下支持Android设备的udev规则配置)
- R语言linux 安装命令,特征之间的相关系数分析实例
- [Linux] 批量把不规则的Android应用程序命名为[中文_版本号](在无中文名称时命名为英文)
- Linux tomcat服务器与android 4.1手机应用交户实例
- 深入理解SELinux/SEAndroid
- 深入理解SELinux/SEAndroid(第一部分)
- 通过Java语言,执行Linux命令并获得反馈数据。--适用于Android系统
- Android各国语言Values文件夹命名规则
- Android各国语言Values文件夹命名规则
- Android中values各国语言命名规则
- Android各国语言Values文件夹命名规则
- selinux android property_context作用(待完成)
- android 下linux的I2C 读写函数实例
- Linux内核入门—— 内核汇编语言规则
- 深入理解SELinux SEAndroid(第二部分)