Android SELinux 知识点
运行模式
SELinux 按照默认拒绝的原则运行:任何未经明确允许的行为都会被拒绝。SELinux 可按两种全局模式运行:
- 宽容模式:权限拒绝事件会被记录下来,但不会被强制执行。
- 强制模式:权限拒绝事件会被记录下来并强制执行。
调试中修改运行模式
获取运行模式
getenforce
//Enforcing: seLinux已经打开;
//Permissive:seLinux已经关闭;
修改运行模式
//关闭selinux
setenforce 0
//打开selinux
setenforce 1
编译选择运行模式
- 在内核中启用 SELinux
// kernel/configs/android-5.4/android-base.config
CONFIG_SECURITY_SELINUX=y
- 更改 kernel_cmdline参数
//device/qcom/msmnile_gvmq/BoardConfig.mk
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
这仅适用于初始制定设备政策的情况。在拥有初始引导程序政策后,请移除此参数,以便将设备恢复强制模式,否则设备将无法通过 CTS 验证。
标签、规则和域
SELinux 依靠标签来匹配操作和政策。标签用于决定允许的事项。套接字、文件和进程在 SELinux 中都有标签。SELinux 在做决定时需参照两点:一是为这些对象分配的标签,二是定义这些对象如何交互的政策。
在 SELinux 中,标签采用以下形式:user:role:type:mls_level(如u:r:init:s0),其中 type 是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。对象会映射到类,对每个类的不同访问类型由权限表示。(type是关键中的关键。)
政策规则采用以下形式:allow domains types:classes permissions;,
#表示init进程可以对chr_file类型的 ipa_dev具有open权限
# Domain -> init
# Type -> ipa_dev
# Class -> chr_file
#Permission -> open
allow init ipa_dev : chr_file { open };
其中:
- Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。
- Type - 一个对象(例如,文件、套接字)或一组对象的标签。
- Class - 要访问的对象(例如,文件、套接字)的类型。
- Permission - 要执行的操作(例如,读取、写入)。
相关文件
在 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 及更高版本中,该政策对应于供应商映像组件的相关政策)。
位置 | 包含 |
---|---|
system/sepolicy/public | 平台的 sepolicy API |
system/sepolicy/private | 平台实现详情(供应商可以忽略) |
system/sepolicy/vendor | 供应商可以使用的政策和上下文文件(供应商可以根据情况忽略) |
BOARD_SEPOLICY_DIRS | 供应商 sepolicy |
关键文件
- BoardConfig.mk
定义 vendor sepolicy
TARGET_SEPOLICY_DIR := ***
- file_contexts
需要在此处添加进程声明 (PS : 如果是增量添加,一定要在末尾空一行。否则编译会报错。)
/(vendor|system/vendor)/bin/hw/android\.hardware\.vibrator@1\.0-service u:object_r:hal_vibrator_default_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.vr@1\.0-service u:object_r:hal_vr_default_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.wifi\.offload@1\.0-service u:object_r:hal_wifi_offload_default_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.wifi@1\.0-service u:object_r:hal_wifi_default_exec:s0
- hal_vibrator.te
相关进程需要申请的权限,需要在此处添加。
# HwBinder IPC from client to server
binder_call(hal_vibrator_client, hal_vibrator_server)
add_hwservice(hal_vibrator_server, hal_vibrator_hwservice)
allow hal_vibrator_client hal_vibrator_hwservice:hwservice_manager find;
# vibrator sysfs rw access
allow hal_vibrator sysfs_vibrator:file rw_file_perms;
allow hal_vibrator sysfs_vibrator:dir search;
- hwservice.te
声明hidl serivce 类型,需要配合hwservice_contexts一起使用。
//生命 hal_vibrator_hwservice 归为 hwservice_manager_type 一类。
type hal_vibrator_hwservice, hwservice_manager_type;
type hal_vr_hwservice, hwservice_manager_type;
type hal_weaver_hwservice, hwservice_manager_type;
type hal_wifi_hwservice, hwservice_manager_type;
- hwservice_contexts
用于声明HIDL service 安全上下文。
//格式
//包名::接口 属性
//包名:android.hardware.vibrator 接口:IVibrator.hal Type:
android.hardware.vibrator::IVibrator u:object_r:hal_vibrator_hwservice:s0
android.hardware.vr::IVr u:object_r:hal_vr_hwservice:s0
android.hardware.weaver::IWeaver u:object_r:hal_weaver_hwservice:s0
android.hardware.wifi::IWifi u:object_r:hal_wifi_hwservice:s0
如何新增
辅助参考
- /system/sepolicy/public/domain.te
- /system/sepolicy/public/te_macros
重要类型/属性
步骤
- 1 添加启动rc
service hal_vendorlight /vendor/bin/hw/vendorlight@1.0-service
class core
- 2 在file_contexts 添加type
/vendor/bin/hw/vendorlight@1.0-service u:object_r:hal_vendorlight_exec:s0
- 3 添加相关.te
# vendorlight service
type hal_vendorlight, domain;
type hal_vendorlight_exec, exec_type, file_type;
init_daemon_domain(foo)
调试相关
neverallow
- 1 添加权限
在mediaserver.te中添加
allow mediaserver device:chr_file { read write open};
- 2 编译报错
libsepol.check_assertion_helper: neverallow on line 258 ofexternal/sepolicy/domain.te (or line 5252 of policy.conf) violated byallow mediaserver device:chr_file { read write open};
违反了domain.te 258:
neverallow {domain –unconfineddomain –ueventd } device:chr_file { open read write}
此句表示 所有domain(声明为domain 的域 type *, domain) 除了unconfineddomain 和 ueventd 的type之外(–unconfineddomain –ueventd, -表示移除) 都不允许对device的chr_file进行 open read write 操作。
- 3 运行Log:
avc: denied { read write } for pid=303 comm="mediaserver"name="tfa9890" dev="tmpfs" ino=3880 scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0tclass=chr_file permissive=0
- 4 修改步骤:
- 目标名称是: tfa9890, 其在系统中的路径是: /dev/tfa9890, 是audio相关的设备文件
- 源类型是mediaserver, 在mediaserver.te 文件中发现其具有 audio_device 目标类型的权限
- 所以在file_contexts 中添加 /dev/tfa9890 u:object_r:audio_device:s0可以解决问题
通过增加 typeattribute来解决
- 1 查看声明的属性 hal_attribute 这个宏在 te_macros 展开
# system/sepolicy/public/attribute
hal_attribute(health_storage);
hal_attribute(input_classifier);
hal_attribute(ir);
hal_attribute(keymaster);
hal_attribute(light);
hal_attribute(lowpan);
hal_attribute(memtrack);
hal_attribute(neuralnetworks);
- 2 hal_attribute 展开后 划等号的 语法
# system/sepolicy/public/te_macros
#####################################
# hal_attribute(hal_name)
# Add an attribute for hal implementations along with necessary
# restrictions.
define(`hal_attribute', `
attribute hal_$1;
expandattribute hal_$1 true;
attribute hal_$1_client;
expandattribute hal_$1_client true;
attribute hal_$1_server;
expandattribute hal_$1_server false;
``
- 3 hal_attribute_hwservice 也是个宏定义,需要在te_macros 中展开
```clike
# system/sepolicy/public/hal_light.te
# HwBinder IPC from client to server, and callbacks
binder_call(hal_light_client, hal_light_server)
binder_call(hal_light_server, hal_light_client)
hal_attribute_hwservice(hal_light, hal_light_hwservice)
allow hal_light sysfs_leds:lnk_file read;
allow hal_light sysfs_leds:file rw_file_perms;
allow hal_light sysfs_leds:dir r_dir_perms;
- 4 hal_attribute_hwservice 展开
# system/sepolicy/public/te_macros
###########################################
# hal_attribute_hwservice(attribute, service)
# Ability for domain to get a service to hwservice_manager
# and find it. It also creates a neverallow preventing
# others from adding it.
#
# Used to pair hal_foo_client with hal_foo_hwservice
define(`hal_attribute_hwservice', `
allow $1_client $2:hwservice_manager find;
add_hwservice($1_server, $2)
build_test_only(`
neverallow { domain -$1_client -$1_server } $2:hwservice_manager find;
')
')
增加权限
过滤
常规
dmesg | grep 'avc: '
or
// hal_vendorlight 是根据 type hal_vendorlight, domain;
logcat -b all | grep hal_vendorlight
以宽容模式启动系统,看看在启动时会遇到哪些拒绝事件:
在 Ubuntu 14.04 或更高版本中:
adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
在 Ubuntu 12.04 中:
adb shell su -c dmesg | grep denied | audit2allow
根据avc提示添加
auditd : avc: denied { add } for interface=android.hidl.base::IBase pid=438 scontext=u:r:hal_vendorlight:s0 tcontext=u:object_r:hidl_base_hwservice:s0 tclass=hwservice_manager permissive=1
以下是此拒绝事件的关键元素:
- 操作 - 试图进行的操作使用括号突出显示:add 。
- 操作方 - scontext(来源环境)条目表示操作方;hal_vendorlight。
- 对象 - tcontext(目标环境)条目表示正在对哪个对象执行操作;hidl_base_hwservice
- 结果 - tclass(目标类别)条目表示当前操作对象的类型;hwservice_manager
常见问题
auditd : avc: denied { find } for interface=vendor.leo.light::ILightVendor pid=438 scontext=u:r:hal_vendorlight:s0 tcontext=u:object_r:default_android_hwservice:s0 tclass=hwservice_manager permissive=1
auditd : avc: denied { add } for interface=vendor.leo.light::ILightVendor pid=438 scontext=u:r:hal_vendorlight:s0 tcontext=u:object_r:default_android_hwservice:s0 tclass=hwservice_manager permissive=1
注意此处的提示 对default_android_hwservice的hwservice_manager 缺少 add find 权限,切记不可直接allow hal_vendorlight default_android_hwservice:hwservice_manager { add find },。
正确的做法是
- 1 在hwservice_contexts 声明
vendor.leo.light::ILightVendor u:object_r:hal_light_leo_hwservice:s0
- 2 在hwservice.te 声明为 hwservice_manager_type 的类型
type hal_light_leo_hwservice , hwservice_manager_type;
- 3 再向 hal_light_leo_hwservice 加权限
allow hal_vendorlight hal_leo_yft_hwservice:hwservice_manager { add find };
参考
Android 中的安全增强型 Linux
Android P添加一个可以让system_server进程访问的hal service需要改动的sepolicy文件
Android O selinux违反Neverallow解决办法
Android : SELinux 简析&修改
Android sepolicy简要记