Android HIDL模型下HAL Service添加SELinux规则实战


引言

  又是新的一年开端,在这里给大家拜一个晚年了!年前有个小伙伴咨询关于HIDL模型下HAL Service服务怎么添加SELinux的规则问题。大家都懂的,快过年的时候基本都没有心情干啥事情了,所以也没有及时的回复了。这不新的一年开端,就给安排上了。由于这是一篇偏向实战类型的博客,所以没有啥矫揉造作的,直接开干就是了。

这里对于什么是HIDL,HAL就不是本文重点介绍的内容了。说出来不怕大伙笑话,其实我也没有单独完成过一个HAL的编写,基本都是改改别人的。




一.前期说明

  在正式开始相关的规则添加前,十分有必要交代清楚我们要添加的HAL Service所对应的HIDL信息!正所谓磨刀不误砍柴工吗,不要急于一时。且听我慢慢道来!

1.1 HIDL服务实现的载体文件

用通俗的一句话来说就是HIDL服务的具体实现者,这里的实现是一个本地进程文件,如下:

vendor.hardware.demo@1.0-service

1.2 HIDL服务具体实现的接口

用通俗的一句话来说就是HIDL服务要实现的接口,他是.hal文件通过hidl-gen生成而来,如下

vendor.hardware.demo::IDemo

1.3 定义BOARD_SEPOLICY_DIRS目录

这里我们为了方便SELinux规则的添加,我们可以定义一个自己设备的SEPOLICY目录,然后添加到对应的BoardConfig.mk下,譬如:

BOARD_SEPOLICY_DIRS += device/xxx/sepolicy

1.4 了解Android SEPOLICY预定义宏

Android为了我们方便SELinux的开发调试,预先定义了一些宏,这个我们十分有必要了解一下,它定义的文件如下:

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;

neverallow { hal_$1_server -halserverdomain } domain:process fork;
# hal_*_client and halclientdomain attributes are always expanded for
# performance reasons. Neverallow rules targeting expanded attributes can not be
# verified by CTS since these attributes are already expanded by that time.
build_test_only(`
neverallow { hal_$1_server -hal_$1 } domain:process fork;
neverallow { hal_$1_client -halclientdomain } domain:process fork;
')
')


#####################################
# hal_server_domain(domain, hal_type)
# Allow a base set of permissions required for a domain to offer a
# HAL implementation of the specified type over HwBinder.
#
# For example, default implementation of Foo HAL:
#   type hal_foo_default, domain;
#   hal_server_domain(hal_foo_default, hal_foo)
#
define(`hal_server_domain', `
typeattribute $1 halserverdomain;
typeattribute $1 $2_server;
typeattribute $1 $2;
')

#####################################
# hal_client_domain(domain, hal_type)
# Allow a base set of permissions required for a domain to be a
# client of a HAL of the specified type.
#
# For example, make some_domain a client of Foo HAL:
#   hal_client_domain(some_domain, hal_foo)
#
define(`hal_client_domain', `
typeattribute $1 halclientdomain;
typeattribute $1 $2_client;

# TODO(b/34170079): Make the inclusion of the rules below conditional also on
# non-Treble devices. For now, on non-Treble device, always grant clients of a
# HAL sufficient access to run the HAL in passthrough mode (i.e., in-process).
not_full_treble(`
typeattribute $1 $2;
# Find passthrough HAL implementations
allow $2 system_file:dir r_dir_perms;
allow $2 vendor_file:dir r_dir_perms;
allow $2 vendor_file:file { read open getattr execute map };
')
')

#####################################
# init_daemon_domain(domain)
# Set up a transition from init to the daemon domain
# upon executing its binary.
define(`init_daemon_domain', `
domain_auto_trans(init, $1_exec, $1)
')

###########################################
# add_hwservice(domain, service)
# Ability for domain to add a service to hwservice_manager
# and find it. It also creates a neverallow preventing
# others from adding it.
define(`add_hwservice', `
  allow $1 $2:hwservice_manager { add find };
  allow $1 hidl_base_hwservice:hwservice_manager add;
  neverallow { domain -$1 } $2:hwservice_manager add;
')




二.添加对应规则

  好了 提前亮也准备得差不多了,是时候开始相关的规则编写了。准备投入战斗,正式开始!

2.1 添加hal_hidl_demo.te

在我们前面的BOARD_SEPOLICY_DIRS文件夹中,添加hal_hidl_demo.te文件,添加如下的规则

# type hal_hidl_demo, domain;
# type hal_hidl_demo_service, vendor_service, service_manager_type;
# type hal_hidl_demo_hwservice, hwservice_manager_type, protected_hwservice;
# type hal_hidl_demo_default_exec, exec_type, vendor_file_type, file_type;
# init_daemon_domain(hal_hidl_demo);



# get_prop(hal_hidl_demo, hwservicemanager_prop)
# add_hwservice(hal_hidl_demo, hal_hidl_demo_hwservice)
# hwbinder_use(hal_hidl_demo);


# allow platform_app hal_hidl_demo_hwservice:hwservice_manager { find };
# allow platform_app hal_hidl_demo:binder {call};


hal_attribute(hidl_demo);
type hal_hidl_demo_default, domain, mlstrustedsubject;
hal_server_domain(hal_hidl_demo_default, hal_hidl_demo);
type hal_hidl_demo_default_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_hidl_demo_default);

#Allow hwbinder call form hal client to server
binder_call(hal_hidl_demo_client, hal_hidl_demo_default_exec)

#add hwservice related rules
type hal_hidl_demo_service, vendor_service, service_manager_type;
type hal_hidl_demo_hwservice, hwservice_manager_type, protected_hwservice;
get_prop(hal_hidl_demo, hwservicemanager_prop)
add_hwservice(hal_hidl_demo_server, hal_hidl_demo_hwservice)
allow hal_hidl_demo_client hal_hidl_demo_hwservice:hwservice_manager find;
hal_client_domain(system_server, hal_hidl_demo)
hwbinder_use(hal_hidl_demo);


allow {  platform_app shell } hal_hidl_demo_hwservice:hwservice_manager { find };
allow {  platform_app shell } hal_hidl_demo:binder {call};

上面被注释掉的,就是不借助宏而添加的规则,这个读者朋友们可以自行体会和实施。


2.2 修改file_contexts文件

修改file_contexts文件,直接添加如下定义:

/vendor/bin/hw/vendor\.hardware\.demo@1\.0-service           u:object_r:hal_hidl_demo_default_exec:s0

这里简单补充一下file_contexts的说明,file_contexts 用于为文件分配标签,并且可供多种用户空间组件使用。在创建新政策时,请创建或更新该文件,以便为文件分配新标签。如需应用新的 file_contexts,请重新构建文件系统映像,或对要重新添加标签的文件运行 restorecon。在升级时,对 file_contexts 所做的更改会在升级过程中自动应用于系统和用户数据分区。此外,您还可以通过以下方式使这些更改在升级过程中自动应用于其他分区:在以允许读写的方式装载相应分区后,将 restorecon_recursive 调用添加到 init.board.rc 文件中


2.3 修改hwservice_contexts文件

修改hwservice_contexts文件,直接添加如下定义:

vendor.hardware.demo::IDemo                                   u:object_r:hal_hidl_demo_hwservice:s0

这里简单补充一下hwservice_contexts的说明,用于为 Android HWBinder 服务分配标签,以便控制哪些进程可以为相应服务添加(注册)和查找(查询)Binder 引用。在启动期间,hwservicemanager 进程会读取此配置。


2.4 修改service_contexts文件

修改service_contexts文件,直接添加如下定义:

vendor.hardware.demo.IDemo/default                               u:object_r:hal_hidl_demo_service:s0

这里简单补充一下service_contexts的说明,用于为 Android Binder 服务分配标签,以便控制哪些进程可以为相应服务添加(注册)和查找(查询)Binder 引用。在启动期间,servicemanager 进程会读取此配置。


2.5 编译验证

相关规则添加OK以后,无需完全整编译Android系统,可以通过make selinux_policy来执行,然后将相关规则重新push到终端即可,这里提供一个简单脚本文件,如下:

adb push ./out/target/product/XXX/system/etc/selinux/*  /system/etc/selinux/
adb push ./out/target/product/XXX/vendor/etc/selinux/*  /vendor/etc/selinux/

adb push ./out/target/product/XXX/system/system_ext/etc/selinux/*  /system/system_ext/etc/selinux/

adb push ./out/target/product/XXX/system/product/etc/selinux/*  /system/product/etc/selinux/
adb push ./out/target/product/XXX/root/sepolicy  /

重启终端,查看HIDL Service是否运行!肯定是能运行的拉。这点信任还是必须有的不是。

console:/ # getenforce
Enforcing
console:/ # ps -A | grep vendor
system         2690      1 2168492  10092 binder_thread_read  0 S vendor.hardware.demo@1.0-service



写在最后

  好了今天的博客Android HIDL模型下HAL Service添加SELinux规则实战就到这里了。总之,青山不改绿水长流先到这里了。如果本博客对你有所帮助,麻烦关注或者点个赞,如果觉得很烂也可以踩一脚!谢谢各位了!!最后附上完整的相关改动点,希望能帮助到各位!
HIDL Service相关规则改动点

GitHub 加速计划 / sel / selinux
150
64
下载
common selinux implementation
最近提交(Master分支:2 个月前 )
1b71cb46 pwalk, pwalkdir: fix walk vs remove race 1 年前
40a1afee Misc nitpicks 1 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐