终于把2个月纠结的功能做完了。 完成功能特地也总结一下
一些常用的命令
1.1 adb shell getenforce (查看selinux 当前的状态)
Enforcing: 代表SELinux处于开启状态,会阻止进程违反SELinux策略访问资源的行为。
Permissive: 代表SELinux关闭,不会阻止进程违反SELinux策略访问资源的行为。
1.2
设置selinux 的状态 adb shell setenforce (开发时 userdebug 或者 eng )
0 Permissive:
1 Enforcing:
1.3
ls -Z XXX , ls -Z 查看文件上下文
ps -Z XXX , ps -Z ps -Z | grep qq 查看进程上下文
id -Z 查看当前用户信息
1.4
adb logcat | grep avc
1.5
安装 sudo apt-get install policycoreutils
audit2allow -i xxx.txt
1.6
qcom
make bootimage
adb reboot bootloader
fastboot flash boot
fastboot devices
fastboot reboot
n:
make ramdisk -j16
make bootimage-nodeps -j16
mtk
KK:
./mk project_name mm external/sepolicy
./mk project_name bootimage
L:
mmm external/sepolicy
make -j24 ramdisk-nodeps
make -j24 bootimage-nodeps
由于这里列出来的内容是来自Android 4.3的,而Android 4.3开启的是Permissive的SEAndroid模式。
#Untrusted apps.
type untrusted_app, domain;
permissive untrusted_app;
app_domain(untrusted_app) net_domain(untrusted_app) bluetooth_domain(untrusted_app) unconfined_domain(untrusted_app)
第二个permissive语句指定当domain为init的进程违反SEAndroid安全策略访问资源时,只进行日志输出,而不是拒绝执行。
SEAndroid中共定义了三个拥有巨大权限的attribute , MLS
3.1 mlstrustedsubject 这一attribute包含了所有能越过MLS检查的主体domain
(type AAA, domain , mlstrustedsubject )
在SEAndroid中被分在mlstrustedsubject attribute中的type有adbd、debuggerd、drmserver、init、installd、kernel、mediaserver、netd、surfaceflinger、su、system、vold、zygote。
3.2 mlstrustedsObject 这一attribute包含了所有能越过MLS检查的客体type
被分在mlstrustedobject attribute中的type有alarm_device、ashmem_device、binder_device、log_device、mtp_device、nv_device、powervr_device、
ptmx_device、null_device、cgroup、sysfs、sysfs_writable、sysfs_writable、sysfs_writable、debugfs、apk_data_file、cache_file、dnsproxyd_socket。
(type BBB, dev_type , mlstrustedsObject )
3.3 unconfineddomain: 这一attribute包含了所有拥有无限权限的type , 拥有所有权限可对客体进行任意操作。
(unconfined.te 主要是为unconfineddomain属性制定策略,这些策略基本就是对各种访问客体拥有所有的权限)
被分在unconfineddomain的type有init、kernel、su。
通过system server service 或者 init 启动的service 读写, 然后app 通过binder/socket 等方式连接APP 访问. 此类安全可靠, 并且可以在service 中做相关的安全审查 .
Zygote进程是由init进程创建的,它的启动命令定义在文件system/core/rootdir/init.rc
照猫画虎,我们启动自己的 服务也在 此文件中 system/core/rootdir/init.rc
如果新的设备节点没有在 file_contexts 中定义, 那么默认属于 root 组 , root 所有 6.
* device
-- 类型定义: external/sepolicy/device.te;device/mediatek/common/sepolicy/device.te -- 类型绑定: external/sepolicy/file_contexts;device/mediatek/common/sepolicy/file_contexts
* File 类型:
-- 类型定义: external/sepolicy/file.te;device/mediatek/common/sepolicy/file.te -- 绑定类型: external/sepolicy/file_contexts;device/mediatek/common/sepolicy/file_contexts
* 虚拟File 类型:
-- 类型定义: external/sepolicy/file.te;device/mediatek/common/sepolicy/file.te -- 绑定类型: external/sepolicy/genfs_contexts;device/mediatek/common/sepolicy/genfs_contexts
* Service 类型:
-- 类型定义: external/sepolicy/service.te; device/mediatek/common/sepolicy/service.te -- 绑定类型:external/sepolicyservice_contexts;device/mediatek/common/sepolicy/service_contexts
* Property 类型:
-- 类型定义: external/sepolicy/property.te;device/mediatek/common/sepolicy/property.te -- 绑定类型: external/sepolicy/property_contexts;device/mediatek/common/sepolicy/property_contexts;
7.各种宏要了解 (external/sepolicy/te_macros ),并 mac dac 会区分宏的权限
Apps signed with the platform key.
type platform_app, domain;
permissive platform_app;
app_domain(platform_app) platform_app_domain(platform_app) Access the network. net_domain(platform_app) Access bluetooth. bluetooth_domain(platform_app) unconfined_domain(platform_app) ......
前面在分析seapp_contexts文件的时候,我们提到,使用平台签名的App所运行在的进程的domain指定为”platform_app”。
从上面列出的内容可以看出,platform_app接下来会通过app_domain、platform_app_domain、net_domain、bluetooth_domain和unconfined_domain宏分别加入到其它的domain中去,
以便可以获得相应的权限。接下来我们就以unconfined_domain宏为例,分析platform_app获得了哪些权限。
宏unconfined_domain定义在文件te_macros文件中
......##################################### #
unconfined_domain(domain) # Allow the specified domain to do anything. # define(`unconfined_domain', ` typeattribute $1 mlstrustedsubject; typeattribute $1 unconfineddomain; ') ......
$1引用的就是unconfined_domain的参数,即platform_app。通过接下来的两个typeattribute语句,
为platform_app设置了mlstrustedsubject和unconfineddomain两个属性。也就是说,
mlstrustedsubject和unconfineddomain这两个Type具有权限,
platform_app这个Type也具有。
接下来我们主要分析unconfineddomain这个Type具有哪些权限。
文件unconfined.te定义了unconfineddomain这个Type所具有的权限,如下所示:
一个Type所具有的权限是通过allow语句来描述的,以下这个allow语句:
allow unconfineddomain domain:binder { call transfer set_context_mgr };
表明domain为unconfineddomain的进程可以与其它进程进行binder ipc通信(call),并且能够向这些进程传递Binder对象(transfer),以及将自己设置为Binder上下文管理器(set_context_mgr)。
注意,SEAndroid使用的是最小权限原则,也就是说,只有通过allow语句声明的权限才是允许的,而其它没有通过allow语句声明的权限都是禁止,这样就可以最大限度地保护系统中的资源。
如果我们继续分析app.te的内容,会发现使用第三方签名的App所运行在的进程同样是加入到unconfineddomain这个domain的,如下所示:
# Untrusted apps
type untrusted_app, domain;
permissive untrusted_app;
app_domain(untrusted_app) net_domain(untrusted_app) bluetooth_domain(untrusted_app) unconfined_domain(untrusted_app)
这是不是意味着使用平台签名和第三方签名的App所具有的权限都是一样的呢?
答案是否定的。
虽然使用平台签名和第三方签名的App在SEAndroid安全框架的约束下都具有unconfineddomain这个domain所赋予的权限,
但是别忘记,在进行SEAndroid安全检查之前,使用平台签名和第三方签名的App首先要通过DAC检查,
也就是要通过传统的Linux UID/GID安全检查。由于使用平台签名和第三方签名的App在安装的时候分配到的Linux UID/GID是不一样的,因此就决定了它们所具有权限是不一样的。
8.
必须要理解的一些概念
8.1 DAC和MAC的区别:
DAC核心思想:进程理论上所拥有的权限与执行它的用户的权限相同。比如,以root用户启动Browser,那么Browser就有root用户的权限,在Linux系统上能干任何事情。
MAC核心思想:即任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。
DAC和MAC的联系:
Linux系统先做DAC检查,如果没有通过DAC权限检查,则操作直接失败。通过DAC检查之后,再做MAC权限检查。
8.2 用户(user)和角色(role):
路径:external/sepolicy/users
user u roles { r } level s0 range s0 - mls_systemhigh;
上述语句声明了一个SELinux用户u,它可用的SELinux角色为r,它的默认安全级别为s0,可用的安全级别范围为s0~mls_systemhigh,其中,mls_systemhigh为系统定义的最高安全级别。
路径:external/sepolicy/roles
role r;
role r types domain;
第一个语句声明了一个SELinux角色r;第二个语句允许SELinux角色r与类型domain关联。
对于进程来说,SELinux用户和SELinux角色只是用来限制进程可以标注的类型,
以前面列出的 external/sepolicy/users和external/sepolicy/roles文件内容来例,如果没有出现其它的user或者 role声明,
那么就意味着只有u、r, domain 和mls 安全级别(s0 - mls_systemhigh)可以组合在一起形成一个合法的安全上下文,而其它形式的安全上下文定义均是非法的。
一些好文章,当时解决功能问题的参照