OpenHarmony SELinux开发指导(一)
一、OpenHarmony SELinux概述
简介
OpenHarmony结合系统架构特点,基于安全增强式Linux(Security-Enhanced Linux ,以下简称SELinux)对OpenHarmony操作系统内文件、参数、SA、HDF等系统资源提供强制访问控制保护能力。本文基于SELinux访问控制模型,提供OpenHarmony SELinux功能的开发指导。
OpenHarmony SELinux支持以下功能:
- 支持访问参数、SA、HDF管控。
- 支持设置应用标签。
- 支持策略编译与加载。
- 支持contexts编译与加载。
- 支持编译时策略合理性检查。
基本概念
安全上下文
安全上下文,也通常称为SELinux标签。OpenHarmony SELinux安全上下文的结构是
user:role:type:sensitivity[:category,...]- sensitivity [:category,...]
:user
:用户类型,比如user u roles { r }
,定义user为u的用户,它属于role r
。role
:角色标识符,角色限制了进程在进程上下文中基于角色标识符可转换的类型,其中文件、参数、SA服务、HDF服务等资源的用户类型使用object_r
,进程的用户类型使用r。type
:SELinux类型,在SELinux规则语句中,使用类型定义规则。sensitivity
:分层安全级别,不同安全级别不能相互访问,目前OpenHarmony SELinux仅支持一层安全级别s0
。category
:对特定sensitivity
划分不分层的分类,目前OpenHarmony SELinux已经定义的分类为c0-c1023
,目前的OpenHarmony SELinux策略上未对category进行区分。
主体
表示访问方,主体可以是一个用户、一个进程、一个服务或其他SELinux类型,OpenHarmony SELinux对进程主体分为四大类:Native进程、应用进程、SA进程、HDF进程。
客体
表示被访问方,客体一般是文件、目录、参数、SA服务、HDF服务等系统资源。
sid
安全标识符(Security ID),用于标识进程、文件或其他SELinux对象的唯一标识符。
AVC
访问矢量缓存(Access Vector Cache),用于跟踪和缓存有关访问控制决策的信息,以提高系统的性能和安全性。
TE
类型强制(Type Enforcement),SELinux策略是由多条类型强制规则构成的。
运行模式
OpenHarmony SELinux支持两种运行模式:
Enforcing
,强制模式,拦截未授权行为并打印avc告警。Permissive
,宽容模式,放行未授权行为并打印avc告警。
实现原理
OpenHarmony SELinux通过主体和客体的安全上下文表示主体是否有权限访问客体,在内核态拦截未授权行为。
图1 OpenHarmony SELinux分层架构图
二、OpenHarmony SELinux开发说明
策略目录结构
OpenHarmony SELinux策略文件存放在//base/security/selinux_adapter/sepolicy/ohos_policy
路径下,在该目录下按以下规范存放:
├── 子系统
│ └── 部件
│ ├── public
│ │ └── type1.te
│ ├── vendor
│ │ └── type2.te
│ └── system
│ └── type3.te
系统相关策略存放在system目录下,芯片相关策略存放在vendor目录下,系统和芯片共用的策略存放在public目录下。
通用策略文件介绍
通用策略文件,是指设备开发者进行SELinux策略配置时,涉及修改的文件。
文件名 | 文件说明 |
---|---|
*.te | SELinux策略文件,用于定义类型、配置allow策略、配置neverallow策略。 |
file_contexts | 实体文件标签映射文件,体现实体文件路径与标签的映射关系。 |
virtfs_contexts | 虚拟文件标签映射文件,体现虚拟文件路径与标签的映射关系。 |
sehap_contexts | 应用标签映射文件,体现应用关键信息与应用进程标签、应用数据目录标签的映射关系。 |
parameter_contexts | 参数标签映射文件,体现参数与标签的映射关系。 |
sevice_contexts | SA服务标签映射文件,体现SA服务与标签的映射关系。 |
hdf_service_contexts | HDF服务标签映射文件,体现HDF服务与标签的映射关系。 |
基础策略文件介绍
基础策略文件,是指SELinux基础框架的SELinux策略文件,一般不涉及修改。
文件名 | 文件说明 |
---|---|
security_classes | class定义。 |
initial_sids | sid定义。 |
access_vectors | class支持的具体permission列表。 |
glb_perm_def.spt | class和permission的全局宏定义,可用于简化策略语句。 |
glb_never_def.spt | neverallow的全局宏定义,可用于简化策略语句。 |
mls | 分层安全级别定义。 |
glb_te_def.spt | te规则的全局宏定义,可用于简化策略语句。 |
attributes | 一些通用集合,在定义策略类型时可以指定到特定的集合,则该策略类型会继承该集合的权限。 |
glb_roles.spt | roles定义。 |
users | users定义。 |
initial_sid_contexts | sid的初始标签。 |
fs_use | 各类型文件系统的默认标签。 |
avc日志信息
当系统行为被SELinux拦截时,会在内核日志和hilog中打印相关的avc denied
日志,格式如下:
audit: type=1400 audit(1502458430.566:4): avc: denied { open } for pid=1658 comm="setenforce" path="/sys/fs/selinux/enforce" dev="selinuxfs" ino=4 scontext=u:r:hdcd:s0 tcontext=u:object_r:selinuxfs:s0 tclass=file permissive=1
其中:
open
,表示当前执行的操作权限。pid=1658
,表示主体进程pid
为1658。comm="setenforce"
,表示主体进程名为setenforce
。path="/sys/fs/selinux/enforce"
,表示被访问客体为/sys/fs/selinux/enforce
。dev="selinuxfs"
,表示被访问客体属于selinuxfs这一文件系统。ino=4
,表示文件节点编号为4。scontext=u:r:hdcd:s0
,表示主体SELinux标签为u:r:hdcd:s0
。tcontext=u:object_r:selinuxfs:s0
,表示被访问客体SELinux标签为u:object_r:selinuxfs:s0
。tclass=file
,表示当前执行file的操作类型。permissive=1
,表示当前SELinux处于宽容模式,只告警不拦截。另外,当permissive=0
时,表示强制模式,会告警并拦截。
开发者可以使用关键字avc denied
来过滤日志,对于影响业务的avc告警,可以利用告警提供的信息来编写相应的SELinux策略,例如:
audit: type=1400 audit(1502458430.566:4): avc: denied { open } for pid=1658 comm="setenforce" path="/sys/fs/selinux/enforce" dev="selinuxfs" ino=4 scontext=u:r:hdcd:s0 tcontext=u:object_r:selinuxfs:s0 tclass=file permissive=1
对应TE规则为:
allow hdcd selinuxfs:file open;
策略格式
SELinux策略,又称SELinux规则,通常以allow或neverallow开头,表示允许或禁止某种行为。在设备上使能SELinux时,SELinux会拦截所有未经allow规则授权的行为,配置allow规则可以放行,neverallow规则主要是拦截危险规则的配置。通常allow规则如下:
allow subject object:class permissions;
表示允许subject
对object
进行class
中的permissions
操作,其中:
subject
表示主体,通常为进程的SELinux类型,如init
。object
表示客体,通常为系统资源的SELinux类型,如data_file
。class
表示要执行的操作的类型,如文件操作file、目录操作dir、套接字操作socket。permissions
表示要执行的具体操作,如对文件file的open、read、write。
同理,
neverallow subject object:class permissions;
表示不允许subject
对object
进行class
中的permissions
操作。
策略宏隔离
在考虑设备开发者便利的同时,需要兼顾商用设备安全性,因此OpenHarmony SELinux提供了策略隔离宏,决定在不同版本上策略是否生效。OpenHarmony SELinux中支持对仅在root版本生效的策略做宏隔离,宏名称为debug_only
。在用于设备开发者调试的root版本中,也就是在版本编译命令中指定--build-variant root
时,宏开启。在用于商用发布的user版本中,也就是在版本编译命令中指定--build-variant user
时,宏关闭。该宏的使用方法参考如下:
debug_only(`
allow ueventd init:fd use;
')
另外,OpenHarmony SELinux中也支持对开发者模式的策略做宏隔离,宏名称为developer_only
,该宏默认开启。开发者模式策略是指,为便于使用user版本进行调试开发的开发者,需要开放的一些用于调试的SELinux策略。开发者模式宏的使用方法参考如下:
developer_only(`
allow sh init:fd use;
')
隔离宏 | root版本 | root版本开发者模式 | user版本 | user版本开发者模式 |
---|---|---|---|---|
未隔离的策略 | 生效 | 生效 | 生效 | 生效 |
debug_only隔离的策略 | 生效 | 生效 | 不生效 | 不生效 |
developer_only隔离的策略 | 不生效 | 生效 | 不生效 | 生效 |
三、OpenHarmony SELinux编译与加载
策略编译与加载
OpenHarmony SELinux策略编译流程在编译机中进行,加载流程在init进程启动后执行,总体流程如图:
图1 OpenHarmony SELinux编译和加载流程图
策略编译
OpenHarmony SELinux策略编译主要包括以下流程:
- 按
security_classes, initial_sids, access_vectors, glb_perm_def.spt, glb_never_def.spt, mls, policy_cap, glb_te_def.spt, attributes, .te, glb_roles.spt, users, initial_sid_contexts, fs_use, virtfs_contexts
顺序遍历策略目录//base/security/selinux_adapter/sepolicy/
,得到父目录为system和public的策略文件列表,使用m4宏处理器将策略文件列表拼接成system.conf
中间文件,这里会决定是否展开隔离宏。同理,遍历得到父目录为vendor和public的策略文件列表,使用m4宏处理器将策略文件列表拼接成vendor.conf
中间文件,这里也会决定是否展开隔离宏。 - 使用开源软件checkpolicy将conf中间文件编译为.cil明文策略文件,得到
system.cil
和vendor.cil
。 - 使用开源软件secilc将
system.cil
和vendor.cil
进行合并,编译为二进制策略文件,编译时会进行neverallow检查,违反neverallow时会编译报错,参考OpenHarmony SELinux常见问题。 - 编译后的二进制策略文件会归档到
system.img
中,位于/system/etc/selinux/targeted/policy/policy.31
。
策略加载
OpenHarmony SELinux策略加载主要经过以下流程:
- init进程在启动后,通过开源软件libselinux提供的用户态操作内核态的接口将selinux二进程策略文件加载到内核。
- 然后根据配置文件
/system/etc/selinux/config
中SELINUX字段的值设置运行模式,SELINUX=enforcing
时,设置为强制模式,SELINUX=permissive
时,设置为宽容模式。从OpenHarmony 3.2开始,OpenHarmony SELinux默认以强制模式运行。
contexts编译与加载
OpenHarmony SELinux contexts包括file_contexts
、hdf_service_contexts
、sevice_contexts
、parameter_contexts
、sehap_contexts
。这些文件不随策略编译而编译,需要单独归档。总体流程如图:
图2 OpenHarmony SELinux contexts编译和加载流程图
contexts编译
OpenHarmony SELinux contexts编译主要包括以下流程:
- 分别遍历各类型的contexts文件,得到每个类型contexts的文件列表。
- 对列表分别拼接去重,生成contexts中间文件。
- 对contexts中间文件中使用的SELinux标签校验合法性,得到contexts文件。
- 将contexts归档到
system.img
,位于/system/etc/selinux/targeted/contexts/
。
contexts加载
OpenHarmony SELinux contexts加载按类型不同,加载方式不同:
contexts类型 | 加载方 | 用途 |
---|---|---|
file_contexts | 需要更新文件标签的进程 | 更新文件标签 |
hdf_service_contexts | hdf_devmgr | 管控HDF注册与获取 |
sevice_contexts | samgr | 管控SA注册与获取 |
parameter_contexts | init | 管控参数设置 |
sehap_contexts | appspawn installs |
appspawn:设置应用标签 installs:设置应用数据标签 |