分享好友 最新动态首页 最新动态分类 切换频道
谈谈Android 安全策略SElinux
2024-12-27 11:18

不积跬步无以至千里,补全自己的短板,完善体系,站在巨人的肩膀上,看到的更远,写这篇文章也算是对这个知识点的总结。

,背景

SElinux出现之前,Linux上的安全模型叫DAC(Discretionary Access Control 自主访问控制),它的核心思想就是:进程拥有的权限与执行它的用户权限相同,比如,以root用户启动camera, 那么camera就拥有root的用户权限,我们知道root的权限是很大的,可以说为所欲为。

所以DAC方式管理太过宽松,只要应用获得了root权限,可以在后台做很多我们不知道的事情,所以在4.4之前都建议不要root破解,我记得5.0之前还有很多应用提示“如果想要运行应用,需要root”,现在想想,不知道该应用做了哪些不可告人的事情。

后来,研究过AOSP的应该知道Android5.0算是一次大的跨度升级,在5.0上google启用了新的权限管理,增加了系统安全性

SElinux是一种新的安全模型,称为MAC(Mandatory Access Control 强制访问控制),他的思想就是:任何进程想要在SElinux系统中干任何事, 都必须在安全策略配置文件中赋予权限,凡是没有出现在安全策略配置文件中的权限,进程没有权限操作任何事。

我们来看个例子

 下面这条SELinux语句表示 允许(allow )hal_nfc_default域(domain)中的进程  ”创建“类型为nfc_vendor_data_file的文件

allow hal_nfc_default nfc_vendor_data_file:file { create rw_file_perms };

如果没有在hal_nfc.te中使用上例中的权限配置allow语句,则hal_nfc_default就无法在data目录创建文件,即使hal_nfc_default具有root权限

DAC和MAC对比总结

1)Android 系统先做DAC检查, 如果没有通过DAC检查,操作直接失败,通过DAC后,再做MAC权限检查。

2)SELinux中也有用户的概念,但和Linux中原有的user概念不同, Linux中的超级用户root在SELinux中可能就是一个没权限,没地位打打酱油的“路人甲”。

写这篇文章的目的是跟着前辈的经验,能够看懂现有的策略文件,能够编写新添加的权限文件或语句。

,SELinux Policy 语言介绍

Linux有种思想,即万事万物皆文件,普通文件是文件,目录是文件,设备是文件。

SELinux中,每种东西都会被赋予一个安全属性,官方说法叫Security Context。Security Context(以后用SContext表示)是一个字符串,主要由三部分组成,分为进程和文件两种。

SEAndroid中,进程的SContext可通过ps -ZA命令查看

最左边的LABEL列值进程的SContext,以第一个u:r:init:s0为例,说明代表含义

  • u为user的意思。SEAndroid中定义了一个SELinux用户,值为u。
  • r为role的意思。role是角色之意,它是SELinux中一种比较高层次,更方便的权限管理思路,即Role Based Access Control(基于角色的访问控制,简称为RBAC)。简单点说,一个u可以属于多个role,不同的role具有不同的权限。
  • init,代表该进程所属的Domain为init。MAC的基础管理思路其实不是针对上面的RBAC,而是所谓的Type Enforcement Accesc Control(简称TEAC,一般用TE表示)。对进程来说,Type就是Domain。比如init这个Domain有什么权限,都需要通过[例子1]中allow语句来说明。
  • S0和SELinux为了满足军用和教育行业而设计的Multi-Level Security(MLS)机制有关。简单点说,MLS将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问。

文件的Security Context,可通过ls -lZ命令查看,

上图中倒数第二列为手机内根目录下文件和目录的SContext信息,同样以第一行u:object_r:vendor_file:s0为例,说明代表含义

  • u:同样是user之意,它代表创建这个文件的SELinux user。
  • object_r:文件是死的东西,它没法扮演角色,所以在SELinux中,死的东西都用object_r来表示它的role。
  • vendor_file:死的东西的Type,和进程的Domain其实是一个意思,它表示odm目录对应的Type是vendor_file。
  • s0:MLS的级别。

根据SELinux规范,完整的SContext字符串为

user:role:type[:range]

注意,方括号中的内容表示可选项,s0属于range中的一部分。

,TE介绍

MAC(Mandatory Access Control 强制访问控制)基本管理单位是TEAC(Type Enforcement Access Control), 然后是高一级别的Role Based Accesc Control。RBAC是基于TE的,而TE也是SELinux中最主要的部分。我们常添加的allow就是TE的范畴。

3.1 根据 SELinux 规范,完整的 SELinux 策略规则语句格式为

 

使用政策规则时将遵循的结构示例

 
  • allow:TE的allow语句,表示授权。除了allow之外,还有allowaudit、dontaudit、neverallow等。
  • hal_nfc_default:source type,也叫subject,domain。
  • nfc_vendor_data_file:target type,代表其后的file所对应的Type.
  • file:代表Object Class,它代表能够给subject操作的一类东西。例如File、Dir、socket等。在Android系统中,有一个其他Linux系统没有的Object Class,那就是Binder。
  • create rw_file_perms:在该类Object Class中所定义的操作

下面根据几个实例了解权限的写法

#允许zygote域中的进程search或getattr类型为appdomain的目录。注意,多个perm_set

#可用{}括起来

allow zygote appdomain:dir { getattr search };

#来个复杂点的

#source_type为unconfineddomain target_type为一组type,由
#{ fs_type dev_type file_type }构成。object_class也包含两个,为{ chr_file file }

#perm_set语法比较奇特,前面有一个~号。它表示除了{entrypoint relabelto}之外,{chr_file #file}这两个object_class所拥有的其他操作

allow unconfineddomain {fs_type dev_type file_type}:{ chr_file file }  

 ~{entrypoint relabelto};

#特殊符号除了~外,还有-号和*号,其中

# 1:-号表示去除某项内容。

# 2:*号表示所有内容。

#下面这条语句中,source_type为属于appdomain,但不属于unconfinedomain的进程。

#而 *表示所有和capability2相关的权限

#neverallow:表示绝不允许。

neverallow { appdomain -unconfineddomain } self:capability2 *;

 特别注意,前面曾提到说权限必须显示声明,没有声明的话默认就没有权限。那neverallow语句就没必要存在了。因为”无权限“是不需要声明的。确实如此,neverallow语句的作用只是在生成安全策略文件时进行检查,判断是否有违反neverallow语句的allow语句。

3.2 Object Class有哪些

文件路径: system/sepolicy/private/security_classes

# file-related classes
class filesystem
class file  #代表普通文件
class dir   #代表目录
class fd    #代表文件描述符
class lnk_file  #代表链接文件
class chr_file  #代表字符设备文件

# network-related classes
class socket   #socket
class tcp_socket
class udp_socket

......
class binder   #Android 平台特有的 binder
class zygote   #Android 平台特有的 zygote

3.3 Permissions

指的是某种class 所拥有的权限,以file这种object class而言,拥有的permission如下

查看路径:system/sepolicy/private/access_vectors

#
# Define common prefixes for access vectors
#
# common common_name { permission_name ... }


#
# Define a common prefix for file access vectors.
#

common file
{
    ioctl
    read
    write
    create
    getattr
    setattr
    lock
    relabelfrom
    relabelto
    append
    map
    unlink
    link
    rename
    execute
    quotaon
    mounton
    audit_access
    open
    execmod
    watch
    watch_mount
    watch_sb
    watch_with_perm
    watch_reads
}

从上面例子可以看出SELinux定义perm set方式使用common命令,实际使用中我们可以参考该文件的定义

#除了common外,还有一种class命令也可定义perm set,如下面的例子

#class命令的完整格式是

#class class_name [ inherits common_name ] { permission_name ... }

#inherits表示继承了某个common定义的权限  注意,class命令定义的权限其实针对得就是

#某个object class。它不能被其他class继承

class dir inherits file {

   add_name  remove_name reparent search rmdir open audit_access execmod

}

#来看SEAndroid中的binder和property_service这两个Object class定义了哪些操作权限

class binder {

      impersonate  call set_context_mgr transfer }

class property_service { set }

3.4 type

type命令的完整格式为:type type_id [alias alias_id,] [attribute_id]

其中,方括号中的内容为可选。alias指定了type的别名,可以指定多个别名。

,SELinux应用

上面理论讲述了一堆,估计你已经有点不耐烦,下面我们以实际使用解决问题来说说

SELinux分两种模式:enforceing mode(限制访问) 和permissive mode(只审查权限,不限制)

4.1怎么关闭这个权限限制呢

4.1.1 临时关闭,当你的手机是debug模式时可以通过adb shell设置

setenfroce 0

setenforce 命令修改的是 /sys/fs/selinux/enforce 节点的值,0 表示permissive,1 表示 enforcing,是 kernel 意义上的修改 selinux 的策略。系统重启后,节点值会复位

4.1.2永久关闭

SECURITY_SELINUX 设置为 false,重新编译 kernel

make bootimage 重新编译boot,刷机验证

4.1.3修改代码

设置 ro.boot.selinux=permissive 属性,并且修改在 system/core/init/Android.mk 中设置用于 user 版本下 selinux 模式为 permissive

 

4.2 系统运行权限不够,avc异常处理

在系统开发过程中,经常遇到的一个问题就是没有权限操作某个动作,直观的就是功能未生效。出现此类问题我们可以通过adb logcat 抓取系统log,过滤log中avc子串,看看是否有报对应进程的权限问题。或者关掉权限看看功能是否正常。

案例1,我们抓到一份异常

可以看到INxpNfc没有find权限,分析如下

谁缺少权限:scontext=u:r:hal_nfc_default:s0  ---->hal_nfc_default

对什么缺少权限:tcontext=u:object_r:default_android_hwservice:s0 ---> default_android_hwservice

什么类型的权限:tclass=hwservice_manager ---> hwservice_manager

缺少什么权限:denied{find} --->find

找到关于nfc的te文件按照套路添加定义

allow scontext_type tcontext_type:tclass_type { denied }

故 allow hal_nfc_default default_android_hwservice:hwservice_manager {find}

也可以使用audit2allow工具生成这个sepolicy规则,路径:AOSP/external/selinux/prebuilts/bin

注意:使用这个工具,需要先 souce build/envsetup.sh -->lunch 之后,audit2allow -i avc_log.txt 会在终端输出,如果想输出到指定文件,使用-p 后面跟路径名

BOARD_SEPOLICY_DIRS += device/mediatek/sepolicy 通过这个命令添加厂家自定义的 sepolicy 规则

新添加的这个权限有可能会引起neverallowed,出现问题可以重新定义相同类型的type,以规避权限检查

案例2

SELinux : avc:  denied  { find } for interface=android.hardware.secure_element::ISecureElement sid=u:r:nfc:s0 pid=21355 scontext=u:r:nfc:s0 tcontext=u:object_r:hal_secure_element_hwservice:s0 tclass=hwservice_manager permissive=0

添加权限allow nfc hal_secure_element_hwservice:hwservice_manager find;

会发现编译报错

libsepol.report_failure: neverallow on line 5 of system/sepolicy/public/hal_secure_element.te (or line 19894 of policy.conf) violated by allow nfc hal_secure_element_hwservice:hwservice_manager { find };
libsepol.check_assertions: 1 neverallow failures occurred
Error while expanding policy

解决方案添加hal_client_domain(nfc, hal_secure_element)

4.3 SELinux Android 源码架构

- externel/selinux:包含编译 sepolicy 策略文件的一些实用构建工具
    - external/selinux/libselinux:提供了帮助用户进程使用 SELinux 的一些函数
    - external/selinux/libsepol:提供了供安全策略文件编译时使用的一个工具 checkcon
- system/sepolicy:包含 Android SELinux 核心安全策略(te 文件,编译生成 sepolicy 文件
    - file_contexts: 系统中所有文件的安全上下文
    - property_contexts: 系统中所有属性的安全上下文
    - seapp_contexts:定义用户、seinfo和域之间的关系,用于确定用户进程的安全上下文
    - sepolicy:二进制文件,保存系统安全策略,系统初始化时会把它设置到内核中

SELinux 虚拟文件系统在 sys/fs/selinux 下,该目录下的文件是 SELinux 内核和用户进程进行通信的接口,libselinux 就是利用这边的接口进行操作

 4.3.1 init进程SEAndroid启动源码分析

 

可以看到 SEAndroid 的启动设置在 init 进程内核态执行(first_stage)过程中,selinux_initialize 函数就是主要的初始化过程,包含加载 sepolicy 策略文件到内核的 LSM 模块中。

 

selinux_set_callback
selinux_set_callback 用来向 libselinux 设置 SEAndroid 日志和审计回调函数

selinux_load_policy
这个函数用来加载 sepolicy 策略文件,并通过 mmap 映射的方式将 sepolicy 的安全策略加载到 SELinux LSM 模块中去。

下面具体分析一下流程

 

这里区分了从哪里加载安全策略文件,第一个是从 /vendor/etc/selinux/precompiled_sepolicy 读取,第二个是直接从根目录 /sepolicy
中读取,最终调用的方法都是 selinux_android_load_policy_from_fd

 

(1)set_selinuxmnt 函数设置内核 SELinux 文件系统路径,这里的值为 /sys/fs/selinux,SELinux 文件系统用来与内核空间 SELinux LSM 模块空间。

(2)通过 fstat 获取 sepolicy 文件(fd 值)的状态信息,通过 mmap 函数将文件内容映射到内存中,起始地址为 map

(3)security_load_policy 调用另一个 security_load_policy 函数将已经映射到内存中的 SEAndroid 的安全策略加载到内核空间的 SELinux LSM 模块中去。

 

函数 security_load_policy 的实现很简单,它首先打开 /sys/fs/selinux/load 文件,然后将参数 data 所描述的安全策略写入到这个文件中去。由于 /sys/fs/selinux 是由内核空间的 SELinux LSM 模块导出来的文件系统接口,因此当我们将安全策略写入到位于该文件系统中的 load 文件时,就相当于是将安全策略从用户空间加载到 SELinux LSM 模块中去了。

以后 SELinux LSM 模块中的 Security Server 就可以通过它来进行安全检查

(4)加载完成,释放 sepolicy 文件占用的内存,并且关闭 sepolicy 文件

selinux_init_all_handles
在 init 进程的用户态启动过程中会调用这个函数初始化 file_context、 property_context 相关内容 handler,根据前面的描述,init 进程给一些文件或者系统属性进行安全上下文检查时会使用 libselinux 的 API,查询文件根目录下 file_context、file_context 的安全上下文内容。所以需要先得到这些文件的 handler,以便可以用来查询系统文件和系统属性的安全上下文。

 

4.3.2 SEAndroid 编译

audit2allow -i avc_log.txt 即可自动输出生成的policy 

source build/envsetup.sh

lunch

mma system/sepolicy/
adb push out/target/product/xx/vendor/etc/selinux/ vendor/etc/selinux/
adb push out/target/product/xx/system/etc/selinux/ system/etc/selinux/

参考

深入理解SELinux/SEAndroid(第一部分) - 邓凡平的个人页面 - OSCHINA - 中文开源技术交流社区

android 8.1 安全机制 — SEAndroid & SELinux_岁月斑驳7的博客-CSDN博客_android selinux

最新文章
如何让百度快速收录网站内容?
还是那句话,只要坚持,总会被青睐的。做搜索引擎推广,不可能做完马上见效的,seo是需要时间的,可能你前几天做的事情,过几天百度才会知道。1、网站内部做好。怎么做好?这个问题问的深奥啊,我怎么知道你的网站有没有做好,你的网站我又
虚拟偶像影视动画制作软件(虚拟偶像影视动画制作软件哪个好)
摘要:虚拟偶像影视动画制作软件,虚拟偶像影视动画制作软件现如今,随着科技的迅猛发展,人们对于数字化、虚拟化、智能化工具的需求日益增加。在影视动画行业,虚拟偶像已经成为了一种趋势,不少影视公司纷纷尝试推出自己的虚拟偶像,同时
漫蛙漫画官网入口最新版软件亮点
漫蛙漫画官网入口最新版下载是一款专为漫画爱好者打造的阅读软件。它汇集了丰富的漫画资源,包括各种题材和风格的作品,满足用户的多样化需求。软件界面简洁友好,操作便捷,支持离线下载,让用户随时随地畅享漫画世界。同时,漫蛙漫画还提
一款具有创新性和趣味性的 AI 换脸应用,可让用户体验到摸胸的感觉
AI 换脸技术是近年来计算机视觉和人工智能领域的热门话题,它可以将一个人的脸替换到另一个人的身上,从而实现换脸的效果。而今天我要向大家介绍的是一款具有创新性和趣味性的 AI 换脸应用,它不仅可以让用户体验到换脸的乐趣,还可以让用
【现身】传苹果将推10.8英寸OLED iPad Air;Vision Pro现身中国监管数据库;美格纳中国区总部开业,专注OLED显示驱动芯片等领域
1.美格纳中国区总部在合肥开业,专注OLED显示驱动芯片等领域2.南京高端软件及信息服务产业融合集群专项资金项目,芯视界、芯行纪等上榜3.苹果Vision Pro设备已现身中国监管数据库4.传苹果将推10.8英寸OLED iPad Air5.日本住友重工将推出SiC
全球十大搜索引擎排名,Google高居榜首
【全球十大搜索引擎排名】Google全球市场份额为68%,高居榜首。雅虎第二,市场份额为7%,百度第三,市场份额为6.5%,微软第四,市场份额为 3%,其它依次为eBay、NHN、Yandex、Facebook、Ask和阿里巴巴。另:中国是全球第二大搜索市场,所占
Python爬虫实战,完整的思路和步骤(附源码)
小的时候心中总有十万个为什么类似的问题,今天带大家爬取一个问答类的网站。 本堂课使用正则表达式对文本类的数据进行提取,正则表达式是数据提取的通用方法。 环境介绍: python 3.6 pycharm requests re json 爬虫的
搭建你的网站:Wordpress网站建设指南 – 外贸网站建设,Wordpress网站建设,外贸建站公司,外贸独立站,Wordpress成品网站
在这个数字化时代,拥有一个具有吸引力和易用性的网站对于个人和企业而言变得越来越重要。而WordPress作为一个流行的网站建设工具,无疑是许多人首选的选择。今天,我们将向您介绍如何搭建属于您自己的网站,让您在网上展示自己的独特风采
【8735(移动版)腾讯手机管家下载】酷派8735 移动版腾讯手机管家16.1.19免费下载
腾讯手机管家专注手机骚扰拦截,动态守护手机安全,深度清理微信、QQ缓存,让手机体积减半,拒绝卡慢。---认真服务---【骚扰拦截】智能拦截骚扰电话,过滤诈骗垃圾短信【清理加速】清理加速能力升级,释放空间告别卡慢【微信清理】个性清理
哪些因素会影响车价计算器的结果?
车价计算器的结果会受到多种因素影响。 贷款金额由车辆价格和首付款比例决定,首付款高贷款金额就低。 贷款利率很关键,不同金融机构和贷款方案利率有差异,利率高还款总额大。 贷款期限也重要,长的每月还款额低但总利息多,短的每月还款
相关文章
推荐文章
发表评论
0评