在Android安全组件中,除了使用传统DAC(Discretionary Access Control)的方式来保护系统文件。但在版本4.4及以后还引入并开启了MAC(Mandatory Access Control)安全框架,使用DAC+MAC组合的方式来保护系统文件及可执行程序的安全。其中被Android所采用的MAC保护框架为SELinux(Security-Enhanced Linux)。
1.Security-Enhanced Linux in Android
开启了MAC框架后,即使是Root用户或具备super权限的进程也会需要完全遵照sepolicy的规则来访问文件。SELinux可以为Android带来如下好处
a).更好地保护和限制系统服务。
b).控制对应用数据和系统日志的访问、降低恶意软件的影。
c).保护用户免遭移动设备上的代码可能存在的缺陷的影响。
SELinux设计时的控制原则为:任何没有被规则允许的操作都会被禁止。但是SELinux框架是支持两种控制模式的
1.Permissive mode, 在不被允许的操作发生后,只是log方式提示,但不禁止。这种模式也只用于调试阶段。
2.Enforcing mode, 在不被允许的操作发生后,除了log方式提示,并且禁止该操作。这种模式则是产品阶段。
2.SELinux 的基本概念
2.1 DAC和MAC的区别
DAC方式,存在所有权的概念,即特定资源的所有者可以控制与该资源关联的访问权限。这种系统通常比较粗放,并且容易出现无意中提权的问题。MAC框架方式则会严格按照预先定义好的sepolicy来允许/拒绝操作。受DAC和MAC同时保护的系统中不会出现获取root的进程能为所欲为的场景。例如,软件通常情况下必须以Root用户帐号的身份运行,才能向原始块设备写入数据。但在基于DAC的传统系统中,如果Root用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。但是在MAC系统中可以使用sepolicy为这些设备添加标签,即使被分配了 Root权限的进程也只可以向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。
2.2 Labels, rules, and domains
SELinux依靠标签(Labels)来匹配操作和政策。标签用于决定允许的事项。套接字(socket)、文件(file)和进程(process)在SELinux中都有标签。SELinux在做决定时需参照以下两点:
a)为对象(socket/file/process/etc…)分配正确的标签。
b)定义对象的交互政策。
在 SELinux 中,标签采用以下形式
user:role:type:mls_level,主要注意下type就行了。一个基本的规则如下
allow domains types:classes permissions;
其中:
Domain: 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。
Type: 一个对象(例如,文件、套接字)或一组对象的标签。
Class: 要访问的对象(例如,文件、套接字)的类型。
Permission: 要执行的操作(例如,读取、写入)。
下面则是一个具体的使用实例
allow appdomain app_data_file:file rw_file_perms;
这表示所有appdomain都可以读取和写入带有 app_data_file 标签的文件。一个 domain 通常对应一个进程,而且具有与其关联的标签。至此sepolicy的基本规则也说的差不多了,下面进入正题。
3.添加sepolicy规则到Android
sepolicy的添加也需要使用到Android的编译系统,下面则是添加自定义sepolicy的写法
//test/flagstaffTest/BoardConfig.mk
BOARD_VENDOR_SEPOLICY_DIRS += \
test/flagstaffTest/sepolicy
BOARD_VENDOR_SEPOLICY_DIRS关键字用于告知编译系统哪些目录下包含sepolicy,对于测试代码的sepolicy都放置于目录test/flagstaffTest/sepolicy下。其结构如下
flagstaff@flagstaff-pc:~/aosp_r.lns/test/flagstaffTest$ tree sepolicy/
sepolicy/
├── file_contexts
├── hal_customehardware_default.te
├── hwservice_contexts
└── hwservice.te
3.1.file_contexts
//file:file_contexts
type hal_customehardware_hwservice, hwservice_manager_type;
定义标签hal_customehardware_hwservice,并且其继承自标签hwservice_manager_type,即针对hwservice_manager_type标签的规则也适用于hal_customehardware_hwservice。hwservice_manager_type则是android团队专门为HIDL服务预制的宏定义,其内部包含了HIDL服务必须的权限规则。
3.2.hal_customehardware_default.te
//file:hal_customehardware_default.te
type hal_customehardware_default, domain;
type hal_customehardware_default_exec,exec_type,vendor_file_type,file_type;
init_daemon_domain(hal_customehardware_default);
allow hal_customehardware_default hwservicemanager:binder { call transfer };
//允许标签为hal_customehardware_default的进程访问标签为hwservicemanager_prop的属性。
get_prop(hal_customehardware_default, hwservicemanager_prop)
/*
Ability for domain to add a service to hwservice_manager
and find it. It also creates a neverallow preventing
others from adding it.
*/
add_hwservice(hal_customehardware_default, hal_customehardware_hwservice);
1.定义标签hal_customehardware_default ,并且继承自 domain。domain则代表可执行程序。
2.定义标签hal_customehardware_default_exec,并且继承自exec_type,vendor_file_type,file_type。该标签作用于文件。
3.init_daemon_domain 则是宏定义,使用m4语言书写,展开如下
//file:system/sepolicy/public/te_macros
define(`domain_trans', `
allow $1 $2:file { getattr open read execute map };
allow $1 $3:process transition;
allow $3 $2:file { entrypoint open read execute getattr map };
ifelse($1, `init', `', `allow $3 $1:process sigchld;')
dontaudit $1 $3:process noatsecure;
allow $1 $3:process { siginh rlimitinh };
')
define(`domain_auto_trans', `
domain_trans($1,$2,$3)
type_transition $1 $2:process $3;
')
define(`init_daemon_domain', `
domain_auto_trans(init, $1_exec, $1)
')
所以init_daemon_domain(hal_customehardware_default)展开如下
init_daemon_domain(hal_customehardware_default)
allow init hal_customehardware_default_exec:file { getattr open read execute map };
allow init hal_customehardware_default:process transition;
allow hal_customehardware_default hal_customehardware_default_exec:file { entrypoint open read execute getattr map };
allow hal_customehardware_default init:process sigchld;
dontaudit init hal_customehardware_default:process noatsecure;
allow init hal_customehardware_default:process { siginh rlimitinh };
type_transition init hal_customehardware_default_exec:process hal_customehardware_default;
展开后宏的意图就很明朗了,主要还是为HIDL服务添加必须的规则,提炼公共部分,减少代码量。
3.3.hwservice_contexts
//file:hwservice_contexts
flagstaff.hardware.custom_hardware::ICustomHardware u:object_r:hal_customehardware_hwservice:s0
为HIDL接口添加sepolicy,在android中任何资源都是被管控的,管控的越细腻,系统的安全度也就越高。
3.4.hwservice.te
//file:hwservice.te
/vendor/bin/hw/flagstaff.hardware.custom_hardware@1.0-service u:object_r:hal_customehardware_default_exec:s0
为可执行程序flagstaff.hardware.custom_hardware@1.0-service的标签为u:object_r:hal_customehardware_default_exec:s0。
经过上述配置后,flagstaff.hardware.custom_hardware@1.0-service运行时标签为hal_customehardware_default。
4.规则查看工具
4.1 查看文件的标签
ls -Z
4.2 查看执行程序的标签
ps -Z
另外如果有问题,欢迎留言或者email(836190520@qq.com)我,技术升级在于交流~~