系列文章转如下链接:
Android Display Graphics系列文章-汇总
Android实战经验篇-系列文章汇总
Android实战经验篇-玩转Selinux
本文主要包括部分:
一、Selinux是什么?
1.1 Selinux概述
1.2 Selinux Policy语言
1.3 Selinux for Android
二、Selinux 修改
2.1 问题解决
2.2 修改验证
一、Selinux是什么?
1.1 Selinux概述
SELinux是安全增强型 Linux(Security-Enhanced Linux)的简称,它是 Linux 内核的一个模块,也是 Linux 的一个安全子系统。 SELinux是适用于 Linux 操作系统的强制访问控制 (MAC) 系统。
什么是DAC 和MAC?
DAC:自主访问控制模型(DAC,Discretionary Access Control),主要是控制用户和组的读、写、可执行权限。
如下图,user是system,group是system,去写一个root权限的test.txt文件,就是没权限的。
DAC 的管控颗粒度太大,没法精确控制到某个进程。
MAC:强制访问控制模型(MAC, Mandatory Access Control),解决了DAC权限控制颗粒度太大的问题。开启Selinux的系统中,任何进程做任何事情,都需先在安全策略配置文件中赋予权限。也就是说,不在安全策略配置文件中配置的权限,进程就没有该权限。
类型强制
SELinux实现了一个灵活的MAC机制,叫做类型强制(Type Enforcement,简称TE)
类型强制提供一种机制,将访问策略控制到进程级别。在类型强制下,所有主体和客体都有一个”安全上下文“与它们关联,要访问某个客体,主体的类型必须为客体的类型进行授权。
下表是集成Selinux前后的对比
标准Linux | 集成SElinux的Linux | |
主体(进程)安全属性 | 真实有效的用户和组ID | 安全上下文 |
客体(资源)安全属性 | 访问模式和文件用户以及组ID | 安全上下文 |
访问控制基础 | 进程用户/组ID和文件基于文件的用户/组ID的访问模式 | 在进程类型和文件类型之间声明的许可 |
怎么查看文件和进程的Selinux Context呢?ps 和 ls 都加Z选项。
文件使用ls -alZ
lahaina:/ $ ls -laZ
total 76
drwxr-xr-x 27 root root u:object_r:rootfs:s0 4096 2009-01-01 00:00 .
drwxr-xr-x 27 root root u:object_r:rootfs:s0 4096 2009-01-01 00:00 ..
drwxr-xr-x 2 root root u:object_r:cgroup:s0 4096 2009-01-01 00:00 acct
drwxr-xr-x 30 root root u:object_r:apex_mnt_dir:s0 620 1970-01-01 03:52 apex
lrw-r--r-- 1 root root u:object_r:rootfs:s0 11 2009-01-01 00:00 bin -> /system/bin
lrw-r--r-- 1 root root u:object_r:rootfs:s0 50 2009-01-01 00:00 bugreports -> /data/user_de/0/com.android.shell/files/bugreports
进程使用 ps -elZ
lahaina:/ $ ps -elZ
LABEL F S UID PID PPID C PRI NI BIT SZ WCHAN TTY TIME CMD
u:r:init:s0 4 S 0 1 0 3 19 0 - 3254623 0 ? 00:00:10 init
u:r:kernel:s0 1 S 0 2 0 0 19 0 - 0 0 ? 00:00:00 kthreadd
u:r:kernel:s0 1 I 0 3 2 0 39 -20 - 0 0 ? 00:00:00 rcu_gp
u:r:kernel:s0 1 I 0 4 2 0 39 -20 - 0 0 ? 00:00:00 rcu_par_gp
u:r:kernel:s0 1 I 0 6 2 0 39 -20 - 0 0 ? 00:00:00 kworker/0:0H-events_h+
u:r:kernel:s0 1 I 0 9 2 0 39 -20 - 0 0 ? 00:00:00 mm_percpu_wq
Selinux Context是什么?
安全上下文(Security Context)是SElinux的核心,安全上下文即标签、域、类型等。一个安全上下文由四部分组成:user:role:type[:range]
说明 | 进程安全上下文 u:r:init:s0 | 文件安全上下文 u:object_r:system_data_file:s0 | |
user | 用户,在SEAndroid中为u | u | u |
role | 角色,RBAC | r | object_r |
type | 类型,域 | init | system_data_file |
range | 安全等级 | s0 | s0 |
1.2 Selinux Policy语言
1.2.1 访问向量规则(Access Vector Rules)
先从一个授权的例子了解下基本的语法;
allow platform_app system_data_file:dir search;
Access Vector Rules由五个部分组成:
allow(rule_name):表示规则名称,一共八种类型,详见1.2.2。
platform_app(source_type):源类型,也叫主体,也叫域,通常是尝试访问的进程的域类型。
system_data_file(target_type):目标类型,也叫客体,也叫域,被进程访问的客体的类型。
dir(class):客体类别,指定允许访问的客体的类别。
search(perm_set):许可,象征目标类型允许源类型访问客体类型的访问种类。
上面的规则解释为:拥有域类型platform_app的进程可以对具有system_data_file类型的目录客体进行search操作。
1.2.2 规则名称
allow:表示允许主体对客体执行相应操作。
neverallow:表示不允许主体对客体执行相应操作。
auditallow: 表示即使权限检查成功的操作也被记录,它只是记录,和授予权限无关,要授予权限必须使用alllow。
dontaudit:表示不记录违反规则的决策信息,且违反规则不影响运行。
扩展:实际还有四个allowxperm,dontauditxperm,,auditallowxperm和neverallowxperm,一般不会涉及到,但是,如果增加ioctl权限规则的时候,若通过allow语句不生效,且avc log中包含ioctlcmd = xxxx字段的时候,则需要使用allowxperm。
例如:allow smb self:udp_socket ioctl;//不生效
allowxperm smb self:udp_socket ioctl { SIOCETHTOOL }; //生效
在/system/sepolicy/public/ioctl_defines查找对应的16进制代码,在te文件中增加。
1.2.3 类型(Type)
SElinux没有预定义类型,必须自行声明。从上面的例子看;
type platform_app
这条语句声明了一个type,名字叫“platform_app”。声明类型后就可以在安全上下文、TE规则和其它策略语句中使用它们了。
下面是类型声明的模板:
type 类型名称 [alias 别名集]
类型名称:也叫类型标识符,长度任意,允许包括ASCII字符,数字,下划线(_)和点(.)。
别名集: 一个或多个别名标识符,别名标识符与类型标识符的命名限制是一致的,如果指定的不止一个别名标识符,要在一对大括号中用空格将各个别名区别开来,如:alias {aliasa_t aliasb_t}。
1.2.4 属性(attribute)
属性可以理解为type group。属性使得"组访问"更容易指定,通过将所有关联的文件类型定义一个属性,然后授予该属性的访问权。那么所有“组内”的成员都有对应的权限了。
从domain例子看起:
attribute domain
这个语句声明一个叫做domain的属性
type platform_app, domain;
这个语句声明了一个type叫platform_app,并关联到了domain。
那么domain的权限,platform就全部都有了。
另外一种关联语法:
typeattribute audioserver coredomain;
将audioserver 关联到了coredomain属性。
当然,这个在客体类型也是通用的:
type sysfs_usb, fs_type, sysfs_type;
1.2.5 宏(Macro)
和C语言一样,Selinux也支持宏,Android 提供了一组宏来处理最常见的情况。Android中定义了很多的宏。例如:
allow init console_device:chr_file rw_file_perms;
domain_auto_trans(shell, vendor_shell_exec, vendor_shell)
更多的宏定义详见:
\system\sepolicy\public\global_macros
\system\sepolicy\public\te_macros
1.2.6 类型转变规则(type_transition)
type_transition规则指定用于域转换或对象创建的默认类型。
1)主体类型转变
Android中通过init进程启动的一些进程,必须指定新的类型,不能在init域。
例子:smb服务在init.rc中启动,开机执行/system/bin/test
/system/bin/test u:object_r:test_exec:s0
可以在test.te加入如下代码
init_daemon_domain(test);
解释:在init服务中启动test_exec标记的进程时,进程转变到test域。
从下面宏的调用流程就能看出,可执行文件都是_exec的type。
domain_auto_trans(init, $1_exec, $1)-->domain_trans($1,$2,$3)-->define(`domain_trans', `# Old domain may exec the file and transition to the new domain.allow $1 $2:file { getattr open read execute map };allow $1 $3:process transition;........')
2)客体类型转变
为进程新建的文件添加自定义标签
file_type_auto_trans(test, system_data_file,test_data_file);
解释:当域在标记为system_data_file的目录中创建新文件时,自动使用test_data_file标记这些文件。
余下内容请转文末链接查看。
1.3 Selinux for Android
1.3.1 Android中SElinux关键文件
二、Selinux修改
2.1 问题解决
2.1.1 SElinux问题确认&定位
2.1.2 直接加上缺失权限
2.1.3 MLS问题
2.1.4 neverallow问题
2.1.4.1 关联到可以访问的域
2.1.4.2 为新服务添加标签
2.1.4.3 为节点创建新的标签
2.1.5 SElinux权限添加规则
2.2 修改验证
2.2.1 Android源码修改验证
1)单独编译
2)单独替换(按照修改的范围选择进行push)
2.2.2 设备端修改验证
系列文章转如下链接,持续更新中。。。
Android Display Graphics系列文章-汇总
Android实战经验篇-系列文章汇总
Android实战经验篇-玩转Selinux