本篇主要讲述Android SELinux的基本概念,包含类型、属性、规则,Sepolicy的核心模块、关键文件,SELinux配置的步骤、调试验证方法等。
作为Android安全模型的一部分,Android使用安全增强型Linux(SELinux)对所有进程强制执行强制访问控制(MAC),甚至包括以Root/超级用户权限运行的进程(Linux功能)。借助SELinux,Android可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。
SELinux按照默认拒绝的原则运行:任何未经明确允许的行为都会被拒绝。SELinux可按两种全局模式运行:
在选择强制执行级别时只能二择其一,您的选择将决定您的政策是采取操作,还是仅允许您收集潜在的失败事件。宽容模式在实现过程中尤其有用。
安全增强型Linux(SELinux)是适用于Linux操作系统的强制访问控制(MAC)系统
。
作为MAC系统,它与Linux中用户非常熟悉的自主访问控制(DAC)系统
不同。在DAC系统中,存在所有权的概念,即特定资源的所有者可以控制与该资源关联的访问权限。这种系统通常比较粗放,并且容易出现无意中提权的问题。MAC系统则会在每次收到访问请求时都先咨询核心机构,再做出决定。
Android依靠SELinux的类型强制执行(TE)组件来实施其政策。这表示所有对象(例如文件、进程或套接字)都具有相关联的类型。例如,默认情况下,应用的类型为untrusted_app。对于进程而言,其类型也称为域。可以使用一个或多个属性为类型添加注解。属性可用于同时指代多种类型。
对象会映射到类(例如文件、目录、符号链接、socket套接字),并且每个类的不同访问权限类型由权限表示。
例如,file类存在权限open。虽然类型和属性作为Android SELinux政策的一部分会进行定期更新,但权限和类是静态定义的,并且作为新Linux版本的一部分也很少进行更新。
政策规则采用以下格式:allow source target:class permissions;
,其中:
规则的一个示例如下:这表示应用可以读取和写入带有app_data_file
标签的文件。还有其他应用类型。例如,isolated_app用于清单中含有isolatedProcess=true
的应用服务。
allow untrusted_app app_data_file:file { read write };
Android对涵盖应用的所有类型使用名为appdomain的属性,而不是对这两种类型重复同一规则:
# Associate the attribute appdomain with the type untrusted_app.
typeattribute untrusted_app, appdomain;
# Associate the attribute appdomain with the type isolated_app.
typeattribute isolated_app, appdomain;
allow appdomain app_data_file:file { read write };
当编写的规则指定了某个属性名称时,该名称会自动扩展为列出与该属性关联的所有域或类型。一些重要属性包括:
特别是对于文件访问权限,有很多种权限需要考虑。例如,read权限不足以打开相应文件或对其调用stat。为了简化规则定义,Android提供了一组宏来处理最常见的情况
例如,若要添加open等缺少的权限,可以将上述规则改写为:
allow appdomain app_data_file:file rw_file_perms;
查看实用宏的更多示例:
尽可能使用宏,以降低因相关权限被拒而导致失败的可能性。定义类型后,需要将其与所代表的文件或进程相关联。
调试SELinux政策或为文件添加标签时(通过file_contexts
或运行ls -Z
),可能会遇到安全上下文(也称为标签)。
例如u:r:untrusted_app:s0:c15,c256,c513,c768
。安全上下文的格式为:user:role:type:sensitivity[:categories]
。
通常可以忽略上下文的user、role和sensitivity
字段。
从Android S开始,类别被用于:
oem_lock u:object_r:oem_lock_service:s0
说明如下:
rule_name source_type target_type : class perm_set
source_type、target_type使用type、typeattribute、attribute定义
attribute dev_type;
# 定义一个类型,属于dev_type属性
type ttyMT_device, dev_type;
###############以上定义可以拆分为两部分
# 仅定义一个类型
type ttyMT_device;
# 仅把ttyMT_device类型关联到dev_type属性
typeattribute ttyMT_device dev_type;
type oem_lock_service, system_api_service, system_server_service, service_manager_type;
common file {
ioctl read write create getattr setattr lock relabelfrom relabelto
append unlink link rename execute swapon quotaon mounton
}
class类型继承comm类型:
class dir
inherits file
{
add_name
remove_name
reparent
search
rmdir
open
audit_access
execmod
}
Android并不会使用SELinux提供的所有功能。注意以下几点:
u
。必要时,系统会使用安全上下文的类别字段表示实际用户r(适用于主题)
和object_r(适用于对象)
s0
敏感度Android的SElinux可以阅读
system/sepolicy
目录中的文件。这些文件在编译后会包含SELinux内核安全政策,并涵盖上游Android操作系统
通常情况下,不能直接修改system/sepolicy
文件,但可以添加或修改自己的设备专用政策文件(位于/device/manufacturer/device-name/sepolicy
目录中)。在Android 8.0及更高版本中,对这些文件所做的更改只会影响供应商目录中的政策。
无论是哪个Android版本,都仍需要修改以下文件:
SELinux 的构建逻辑位于以下文件中:
可以在上下文的描述文件中为需要的对象指定标签
restorecon
(比如重新加载权限restorecon -R /(对应权限目录)
)。在升级时,对file_contexts
所做的更改会在升级过程中自动应用于系统和用户数据分区。此外,还可以通过以下方式使这些更改在升级过程中自动应用于其他分区:在以允许读写的方式装载相应分区后,将restorecon_recursive
(重载权限)调用添加到init.board.rc
文件中Android Binder服务
分配标签,以便控制哪些进程可以为相应服务添加(注册)和查找(查询)Binder引用。在启动期间,servicemanager
进程会读取此配置proc
或vfat
)分配标签。此配置会作为内核政策的一部分进行加载,但更改可能对内核inode
无效。要全面应用更改,需要重新启动设备,或卸载并重新装载文件系统。此外,通过使用context=mount
选项,还可以为装载的特定系统文件(例如vfat
)分配特定标签seapp_contexts
文件中用作密钥,以便为带有该seinfo标记的所有应用分配特定标签。在启动期间,system_server会读取此配置简单来说:
Android8.0针对file_contexts引入了以下更改:
/system/etc/selinux/plat_file_contexts
下,并由init在启动时加载(与供应商file_context一起加载)/vendor/etc/selinux/vendor_file_contexts
下,并由init在启动时加载(与平台file_context一起加载)在Android8.0中,property_contexts拆分成了两个文件:
/system/etc/selinux/plat_property_contexts
下,并由init在启动时加载(与供应商property_contexts一起加载)/vendor/etc/selinux/vendor_property_contexts
下,并由init在启动时加载(与平台property_context一起加载)在Android8.0中,service_contexts拆分成了以下文件:
/system/etc/selinux/plat_service_contexts
下,并由servicemanager在启动时加载(与供应商service_contexts一起加载)/vendor/etc/selinux/vendor_service_contexts
下,并由servicemanager在启动时加载(与平台service_contexts一起加载)/system/etc/selinux/plat_hwservice_contexts
下,并由hwservicemanager在启动时加载(与vendor_hwservice_contexts一起加载)/vendor/etc/selinux/vendor_hwservice_contexts
下,并由hwservicemanager在启动时加载(与plat_service_contexts一起加载)/vendor/etc/selinux/vndservice_contexts
下,并由vndservicemanager在启动时加载在Android8.0中,seapp_contexts拆分成了两个文件:
/system/etc/selinux/plat_seapp_contexts.
下BOARD_SEPOLICY_DIRS
指向的目录下)进行构建/vendor/etc/selinux/vendor_seapp_contexts
下在Android8.0中,mac_permissions.xml拆分成了两个文件:
/system/etc/selinux/.
下。/vendor/etc/selinux/.
下修改或添加政策文件和上下文的描述文件后,需要更新
/device/manufacturer/device-name/BoardConfig.mk
makefile以引用sepolicy子目录和每个新的政策文件
# 引用目录
BOARD_SEPOLICY_DIRS += \
<root>/device/manufacturer/device-name/sepolicy
# 单独引用
BOARD_SEPOLICY_UNION += \
genfs_contexts \
file_contexts \
sepolicy.te
配置CONFIG_SECURITY_SELINUX=y
(例如kernel/msm-5.4/kernel/configs/android-base.config)
配置BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
仅适用于初始制定设备政策的情况。在拥有初始引导程序政策后,请移除此参数,以便将设备恢复强制模式,否则设备将无法通过CTS验证
adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy
adb logcat -b all | audit2allow -p policy
评估与以下内容类似的警告的输出:init: Warning! Service name needs a SELinux domain defined; please fix!
查看*_contexts
文件,了解之前是如何为内容添加标签的,然后根据对标签含义的了解分配一个新标签。
这个标签最好是能够融入到政策中的现有标签,但有时也需要使用新标签,而且还需要提供关于访问该标签的规则。将标签添加到相应的上下文的描述文件中
可能需要为每一项分别编写一个全新的政策。例如,从init
衍生的所有服务都应该有自己的安全域。以下命令有助于查看保持运行的服务(不过所有服务都需要如此处理):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
在开发过程早期为其提供相应的域,以避免向init添加规则或将init访问权限与其自身政策中的访问权限混淆
通常会为指定的项目新建定义rc文件作一些操作,比如chmod、chown权限赋予、创建文件夹、启动service、重载selinux权限等等
设置BOARD_CONFIG.mk以使用BOARD_SEPOLICY_*
变量(通常不需要修改)
确保每一次使用mount都对应一个添加了适当标签的文件系统,或者指定了context= mount
选项
查看每个拒绝事件,并创建SELinux政策来妥善处理每个拒绝事件
实际进行权限修复修改
集成基本级别的SELinux功能并全面分析结果后,可以添加自己的政策设置,以便涵盖对Android操作系统所做的自定义。这些政策必须仍然满足Android兼容性计划的要求,并且不得移除默认的 SELinux设置
制造商不得移除现有的SELinux政策,否则可能会破坏Android SELinux的实施方式及其管控的应用。这包括可能需要改进以遵守政策并正常运行的第三方应用。应用必须无需任何修改即可继续在启用了SELinux的设备上正常运行
当开始自定义SELinux时,需注意:
如果要自定义SELinux设置,则应格外谨慎,以免破坏现有应用。要开始使用,请按下列步骤操作:
/device/manufacturer/device-name/sepolicy
目录中的*.te
文件内(te
是SELinux政策源代码文件使用的扩展名),然后使用BOARD_SEPOLICY
变量将它们纳入到的build编译中.te
文件中使用宽容声明(调试手法)SELinux基于M4计算机语言,因此支持多种有助于节省时间的宏。
在以下示例中,所有域都被授予向/dev/null
读写数据(write)的权限以及从/dev/zero
读取数据(read)的权限
# Allow read / write access to /dev/null
allow domain null_device:chr_file { getattr open read ioctl lock append write};
# Allow read-only access to /dev/zero
allow domain zero_device:chr_file { getattr open read ioctl lock };
从system/sepolicy/public/global_macros
看到宏定义:
define(`x_file_perms', `{ getattr execute execute_no_trans map }')
define(`r_file_perms', `{ getattr open read ioctl lock map watch watch_reads }')
define(`w_file_perms', `{ open append write lock map }')
define(`rx_file_perms', `{ r_file_perms x_file_perms }')
define(`ra_file_perms', `{ r_file_perms append }')
define(`rw_file_perms', `{ r_file_perms w_file_perms }')
define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
可以使用宏编写替代,简短的编写权限:
# Allow read / write access to /dev/null
allow domain null_device:chr_file rw_file_perms;
# Allow read-only access to /dev/zero
allow domain zero_device:chr_file r_file_perms;
# 类型声明,声明DHCP守护进程将沿用基本的安全政策 (domain)
type dhcp, domain;
# DHCP 被声明为宽容域(后面调试成功后需去除)
permissive dhcp;
type dhcp_exec, exec_type, file_type;
type dhcp_data_file, file_type, data_file_type;
# 该政策声明DHCP是从init衍生而来的,并且可以与其通信
init_daemon_domain(dhcp)
# 该政策允许DHCP使用net域中的常用网络功能,例如读取和写入TCP数据包、通过套接字进行通信,以及执行DNS请求
net_domain(dhcp)
......
# For /proc/sys/net/ipv4/conf/*/promote_secondaries
# 该政策声明DHCP可以向/proc中的特定文件写入数据。这一行显示了SELinux的详细文件标签
# 它使用proc_net标签来限定DHCP仅对/proc/sys/net中的文件具有写入权限
allow dhcp proc_net:file write;
......
# 描述了允许应用之间如何交互。
# 该政策声明DHCP和netd之间可通过文件描述符、FIFO 文件、数据报套接字以及UNIX信息流套接字进行通信。
# DHCP只能向数据报套接字和UNIX信息流套接字中读写数据,但不能创建或打开此类套接字
allow dhcp netd:fd use;
allow dhcp netd:fifo_file rw_file_perms;
allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write };
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket
netlink_nflog_socket } { read write };
BOARD_SEPOLICY_DIRS
,包括用来在不同设备类型之间增强AOSP政策的政策BOARD_SEPOLICY_DIRS
会将该政策仅存放在供应商映像中在Android 8.0及更高版本中,政策位于AOSP中的以下位置:
system/sepolicy/public
:其中包括所导出的用于供应商特定政策的政策。所有内容都会纳入Android 8.0兼容性基础架构。公共政策会保留在不同版本上,因此可以在自定义政策的/public
中添加任何内容。正因如此,可存放在/public
中的政策类型的限制性更强。将此目录视为相应平台的已导出政策API:处理/system与/vendor之间的接口的所有内容都位于这里
system/sepolicy/private
:包括系统映像正常运行所必需(但供应商映像政策应该不知道)的政策system/sepolicy/vendor
:包括位于/vendor
但存在于核心平台树(非设备特定目录)中的组件的相关政策。这是构建系统区分设备和全局组件的软件工件;从概念上讲,这是下述设备专用政策的一部分device/manufacturer/device-name/sepolicy
:包含设备专用政策,以及对政策进行的设备自定义(在Android 8.0及更高版本中,该政策对应于供应商映像组件的相关政策)在Android 11及更高版本中,system_ext
和product
分区还可以包含特定于分区的政策。system_ext
和product
政策也分为公共政策和私有政策,且供应商可以使用system_ext
和product
的公共政策(例如系统政策)
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS
:包括所导出的用于供应商特定政策的政策。已安装到system_ext分区(编译结果会存在system_ext/etc/selinux)SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS
:包括system_ext
映像正常运行所必需(但供应商映像政策应该不知道)的政策。已安装到 system_ext分区(编译结果会存在system_ext/etc/selinux)PRODUCT_PUBLIC_SEPOLICY_DIRS
:包括所导出的用于供应商特定政策的政策。已安装到product分区(主要针对packages/services的权限,编译结果在system/product/etc/selinux)PRODUCT_PRIVATE_SEPOLICY_DIRS
:包括product映像正常运行所必需(但供应商映像政策应该不知道)的政策。已安装到product分区注意:在使用system_ext和product公共政策时要格外小心。公共政策充当system_ext/product和vendor之间的导出API。合作伙伴应自行管理兼容性问题
构建系统采用此策略并在相应分区上生成system、system_ext、product、vendor和odm策略组件。步骤包括:
公共+供应商+BOARD_SEPOLICY_DIRS
组合政策指明必须将哪些部分转换为将与平台政策相关联的属性在Android 11及更高版本中,
system_ext
和product
分区还可以包含特定于分区的政策。宏也会变更,替换原来的BOARD_PLAT_PUBLIC_SEPOLICY_DIR
和BOARD_PLAT_PRIVATE_SEPOLICY_DIR
查看Android 12源码/system/sepolicy/README
的说明:
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS += device/acme/roadrunner-sepolicy/systemext/public
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS += device/acme/roadrunner-sepolicy/systemext/private
PRODUCT_PUBLIC_SEPOLICY_DIRS += device/acme/roadrunner-sepolicy/product/public
PRODUCT_PRIVATE_SEPOLICY_DIRS += device/acme/roadrunner-sepolicy/product/private
The old BOARD_PLAT_PUBLIC_SEPOLICY_DIR and BOARD_PLAT_PRIVATE_SEPOLICY_DIR
variables have been deprecated in favour of SYSTEM_EXT_*.
从Android 11开始,system_ext和product分区可以将其指定的公共类型导出到vendor分区。
当system_ext和product分区基于同一平台版本N时,构建系统会生成到system_ext/etc/selinux/mapping/N.cil
和product/etc/selinux/mapping/N.cil
的基本映射文件,其中包含从type到type_N的身份映射。vendor可以通过版本化属性type_N访问type
使用以下编译标记向 product 分区中安装模块:
使用以下编译标记向system_ext分区中安装模块:(宏的源码参阅build\soong\androidmk\androidmk\android.go
)
LOCAL_PRIVILEGED_MODULE := true
决定在 priv-app 文件中,不加 LOCAL_PRIVILEGED_MODULE
则编译到 system\system_ext\app\检查是否有错误,错误会以事件日志的形式传给dmesg和logcat,并可在设备上从本地查看。 制造商应先检查这些设备上传给dmesg的SELinux输出并优化设置,然后再在宽容模式下公开发布,最后切换到强制模式。 SELinux日志消息中包含“avc:”字样,因此可使用grep找到。可以通过运行
cat/proc/kmsg
来获取当前的拒绝事件日志,也可以通过运行cat/sys/fs/pstore/console-ramoops
来获取上次启动时的拒绝事件日志。
根据这些输出内容,制造商可以轻松发现系统用户或组件违反SELinux政策的行为。然后,制造商便可更改相应软件和/或SELinux政策,以防范此类恶意行为。
avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd"
scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
解读如下:
{connectto}
表示执行的操作。根据它和末尾的tclass(unix_stream_socket)
,可以大致了解是对什么对象执行什么操作。在此例中,是操作方正在试图连接到UNIX信息流套接字scontext(u:r:shell:s0)
表示发起相应操作的环境,在此例中是shell中运行的某个程序tcontext(u:r:netd:s0)
表示操作目标的环境,在此例中是归netd所有的某个unix_stream_socket
comm="ping"
可了解拒绝事件发生时正在运行的程序。在此示例中,给出的信息非常清晰明了<5> type=1400 audit: avc: denied { read write } for pid=177
comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0
tcontext=u:object_r:kmem_device:s0 tclass=chr_file
以下是此拒绝事件的关键元素:
在某些情况下,事件日志中包含的信息不足以查明拒绝事件的来源。通常,获取调用链(包括内核和用户空间)有助于更好地了解发生拒绝事件的原因。 最新的内核定义了一个名为 avc:selinux_audited 的跟踪点。使用
Android simpleperf
可启用此跟踪点并获取调用链。
支持的配置:
mainline
和android12-5.10
),也支持android12-5.4分支。可以使用simpleperf来确定您的设备上是否定义了跟踪点:adb root && adb shell simpleperflist|grep avc:selinux_audited
调用链是一个统一的内核和用户空间调用链,可发起跟踪从用户空间直到内核中发生拒绝事件的位置,更好地查看代码流
获取调用链:
第一步是使用simpleperf record
录制事件:adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
第二步应触发导致拒绝事件的事件。之后,应停止录制。在此例中应使用Ctrl-c
获取样本:^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
最后,可使用simpleperf report
检查获取的堆栈轨迹。 例如:
adb shell -t "cd /data/local/tmp && su root simpleperf report -g --full-callgraph"
[...]
Children Self Command Pid Tid Shared Object Symbol
100.00% 0.00% dmesg 3318 3318 /apex/com.android.runtime/lib64/bionic/libc.so __libc_init
|
-- __libc_init
|
-- main
toybox_main
toy_exec_which
dmesg_main
klogctl
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_syslog
do_syslog
selinux_syslog
slow_avc_audit
common_lsm_audit
avc_audit_post_callback
avc_audit_post_callback
生产设备不支持宽容模式。CTS 测试会确认是否已启用强制模式 SELinux强制模式可以在
userdebug或eng build
中通过ADB停用。运行以下命令:
adb root
# 获取模式
adb shell getenforce
# 设置模式
# 0--代表Permissive
# 1--代表Enforcing
adb shell setenforce 0
# 查看进程的sContext
ps -Z
# 查看文件权限
ls -Z
或在内核命令行中输入以下命令(适用于设备开发初期):
androidboot.selinux=permissive
androidboot.selinux=enforcing
或使用Android 12中的bootconfig功能:
···shell androidboot.selinux=permissive androidboot.selinux=enforcing ···
audit2allow工具可以获取dmesg拒绝事件并将其转换成相应的SELinux政策声明。因此,该工具有助于大幅加快SELinux开发速度 AOSP不再提供audit2allow。需要使用Linux发行版提供的软件包(Debian和Ubuntu上为
policycoreutils-python-utils
软件包)
可以使用linux原生工具,将log输入到log.txt文件,然后执行:
cat log.txt | grep avc | audit2allow
或者
audit2allow -i log.txt
例如:
$ cat log.txt
avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
$ audit2allow -i log.txt
#============= shell ==============
allow shell netd:unix_stream_socket connectto;
在设备运行时,执行以下命令:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
注意:运行这些命令不会更改bugreport.txt,因为所有日志都已经存在,包括上次重新启动之前存在的日志。在设备进行OTA更新或向设备刷入开发版系统时,新旧违规行为会混杂在一起,直到下一次重新启动为止。如需解决此问题,需重新启动设备,或者从错误报告中滤除console-ramoops
和LAST_LOGCAT
例如本地测试执行结果:
~/Documents/temp$ adb pull sys/fs/selinux/policy
sys/fs/selinux/policy: 1 file pulled, 0 skipped. 3.7 MB/s (502496 bytes in 0.128s)
~/Documents/temp$ adb logcat -b events -d|audit2allow -p policy
#============= hal_vehicle_default ==============
allow hal_vehicle_default sysfs:file getattr;
#============= init-insmod-sh ==============
allow init-insmod-sh debugfs:file setattr;
#============= start_natp ==============
allow start_natp unlabeled:dir search;
#============= system_server ==============
allow system_server idmap_exec:file execute;
#============= webview_zygote ==============
allow webview_zygote app_data_file:dir getattr;
不过,必须仔细审核要添加到政策中的条目,以免出现权限过宽的情况。 例如,如果将上面示例的rmt_storage
拒绝事件输入到audit2allow中,会生成以下SELinux政策声明建议:
#============= shell ==============
allow shell kernel:security setenforce;
#============= rmt ==============
allow rmt kmem_device:chr_file { read write };
注意点:这会授予rmt向内核内存写入内容的权限,从而形成明显的安全漏洞。通常情况下,audit2allow给出的声明建议只是一个大致的基础。 在添加这些声明后,可能需要更改来源域和目标标签,并纳入适当的宏,才能实现良好的政策配置。有时,应对拒绝事件的合理方式不是更改政策,而是更改违规的应用。
通过init启动的服务需要在各自的SELinux域中运行。以下示例会将服务“foo”放入它自己的SELinux网域中并为其授予权限。
该服务是在设备的init.device.rc
文件中启动的,如下所示:
service foo /system/bin/foo
class core
1.创建一个新网域“foo”:创建包含以下内容的文件device/manufacturer/device-name/sepolicy/foo.te
:
这是foo SELinux网域的初始模板,可以根据该可执行文件执行的具体操作为该模板添加规则
# foo service
type foo, domain;
type foo_exec, exec_type, file_type;
init_daemon_domain(foo)
2.为/system/bin/foo
添加标签:将以下内容添加到device/manufacturer/device-name/sepolicy/file_contexts:
这可确保为该可执行文件添加适当的标签,以便SELinux在适当的网域中运行相应服务
/system/bin/foo u:object_r:foo_exec:s0
3.构建并刷写启动映像和系统映像。 4.优化相应域的SELinux规则:根据拒绝事件确定所需的权限。audit2allow工具提供了一些实用的指南,但该工具仅适用于提供编写政策时所需的信息。切勿只是复制输出内容。
dac_override拒绝事件意味着违规进程正在尝试使用错误的
unix user/group/world
权限访问某个文件。 正确的解决方案几乎从不授予dac_override权限,而是更改相应文件或进程的unix权限。有些网域(例如 init、vold 和 installd)确实需要能够替换 unix文件权限才能访问其他进程的文件。