Android selinux配置

本文对比介绍了Android O之前与O及以后版本的SELinux配置差异。Android O引入Treble机制,改变了SELinux策略的分离方式。针对不同版本,详细阐述了配置流程,包括设备节点标签化、服务进程权限分配等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近项目上遇到Android selinux权限配置的问题,Android O之前的版本与Android O及之后的版本有较大的差异。Android O引入了Treble机制,为了防止system.img和vendor.img 中的数据、服务、应用等相互依赖、调用和 引用,谷歌大幅度的更新了selinux权限管理,在Android O及以后的版本中,sepolicy进行了分离,与system相关的sepolicy(对应文件路径:/system/sepolicy)打包到system.img,与vendor相关的sepolicy(对应文件路径:/device/mediatek/sepolicy/basic)打包到vendor.img,在终端上生成策略文件路径分别为/system/etc/sepolicy、/vendor/etc/sepolicy。

selinux的原理等网上已经有文章写的非常好(https://blog.youkuaiyun.com/innost/article/details/19299937),本篇文章主要介绍两种系统下的selinux配置方法

1、基于Android O之前的版本的selinux配置

在selinux配置前要先熟悉整体方案在Android系统中的架构,项目的整体框架大致如下:底层的kernel中有设备驱动程序,建立/dev/node的设备节点,hal层封装具体协议,服务程序service跑在系统system server的进程背景下,通过jni对设备节点进行访问,在service中做相关的安全检查,检查通过的apk与service间通过binder机制进行通信及调用,最终操作设备节点

配置思路:定义主体和客体的安全上下文,定义主体对客体的访问权限,通俗一点即为新增的device定义具体的标签,然后给相应的process开启相应的权限。

具体步骤:将设备节点打上标签,将service定义为system_server type,配置system_server对设备节点的操作权限,将service打上标签,将service加到system server进程中,具体修改如下:

1) init.project.rc
chown system system /dev/node
chmod 0666 /dev/node

2) device.te
type xxx_device,dev_type;

3) file_contexts
/dev/node  u:object_r:xxx_device:s0

4) system_server.te
allow system_server xxx_device:chr_file rw_file_perms;

5) service.te
type yyy_server_service, app_api_service,system_server_service,system_manager_type;

6) service_contexts
zzz u:object_r:yyy_server_service:s0

7) frameworks/base/core/java/android/content/Context.java
public static final String YYY_SERVICE = "zzz";
   services/java/com/android/server/SystemServer.java
ServiceManager.addService(Context.YYY_SERVICE, yyyService);

2、基于Android O及之后版本的selinux配置

项目的整体框架为:底层的kernel中有设备驱动程序,建立/dev/node的设备节点,中间件封装具体的协议,HIDL提供独立的进程背景,上层应用程序可以通过C和Java与HIDL服务进行进程间通信。与Android O之前的版本相比,服务不再运行在system server进程背景下,有独立的进程背景。

配置思路:配置HIDL可执行程序对设备节点的访问权限,配置HIDL的server和client,调用者可通过成为HIDL的一个client的方式获取对server的访问权限

几个重要角色:设备节点、HIDL可执行程序(生成的HIDL可执行文件)、HIDL server进程(HIDL可执行程序运行时进程)、HIDL service(注册到系统中的HIDL服务,APK通过获取到HIDL service与之通信)、HILD client(最终调用HIDL的应用程序)

配置步骤:将设备节点打上标签,配置HIDL可执行程序对设备节点的访问权限,配置HIDL的server进程允许使用IBinder IPC通信,配置server进程有权限将HIDL service添加到hwservice_manager并找到这个service,配置server和client的绑定关系,这样就可以通过client与server进行通信,具体修改如下:

1) attributes
attribute hal_issue;
attribute hal_issue_client;
attribute hal_issue_server;

2) file_contexts
/dev/node u:object_r:xxx_device:s0 //给设备节点打上标签
/(vendor|system/vendor)/bin/hw/vendor\.yyy\.device@1\.0-service u:object_r:hal_issue_mtk_exec:s0 //给HIDL的可执行程序打上标签

3) hwservice_contexts
vendor.yyy.device::IDevice u:object_r:hal_issue_hwservice:s0 //给HIDL的服务打上标签

4) hwservice.te
type hal_issue_hwservice, hwservice_manager_type;

5) hal_issue.te
binder_call(hal_issue_client, hal_issue_server) //设置允许hal_issue_client进程 binder IPC to hal_issue_server进程
binder_call(hal_issue_server, hal_issue_client) //设置允许进程hal_issue_server binder IPC to hal_issue_client进程
allow hal_issue_client hal_issue_hwservice:hwservice_manager find; //允许hal_issue_client对hal_issue_hwservice有find权限

6) hal_issue_default.te
type hal_issue_mtk, domain;
type hal_issue_mtk_exec, exec_type, file_type, vendor_file_type; //设置HIDL的可执行程序的属性

init_daemon_domain(hal_issue_mtk) // //通过执行hal_zyitong_qti_exec可执行程序设置从init到hal_zyitong_qti守护进程域的转换:如果没有设置,当hal_zyitong_qti 从init进程fork出来执行后,hal_zyitong_qti会被设置成和init进程拥有一模一样的安全上下文,其拥有和init进程一样的权限
;如果设置之后,则当其从init进程fork出来之后,将被设置成hal_zyitong_service.te为hal_zyitong_qti进程配置的安全上下文,其拥有同init进程不一样的权限.

hwbinder_use(hal_issue_mtk) //允许hal_issue_qti进程使用HwBinder IPC
hal_server_domain(hal_issue_mtk, hal_issue)  //设置hal_issue_server的实现为hal_issue_mtk进程
add_hwservice(hal_issue_mtk, hal_issue_hwservice) //使hal_issue_mtk有能力将hal_issue_hwservice添加到hwservice_manager并找到这个service

allow hal_issue_mtk xxx_device:chr_file { ioctl read write getattr lock append map open }; //配置hal_issue_mtk对xxx_device的操作权限

hal_client_domain(platform_app, hal_issue) //设置platform_app为hal_issue_client的一个client,从而可以与hal_issue_server通信

8) seapp_contexts
user=_app seinfo=platform name=com.xxx domain=platform_app type=app_data_file levelFrom=user // 设置通过平台签名的apk的进程domain为platform_app

9) init.project.rc
chown system system /dev/node
chmod 0666 /dev/node
以下摘抄自 system/sepolicy/public/te_macros

#####################################
# 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)
tmpfs_domain($1)
')

#####################################
# hwbinder_use(domain)
# Allow domain to use HwBinder IPC.
define(`hwbinder_use', `
# Call the hwservicemanager and transfer references to it.
allow $1 hwservicemanager:binder { call transfer };
# Allow hwservicemanager to send out callbacks
allow hwservicemanager $1:binder { call transfer };
# hwservicemanager performs getpidcon on clients.
allow hwservicemanager $1:dir search;
allow hwservicemanager $1:file { read open };
allow hwservicemanager $1:process getattr;
# rw access to /dev/hwbinder and /dev/ashmem is presently granted to
# all domains in domain.te.
')

###########################################
# 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;
')

#####################################
# 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;

#####################################
# binder_call(clientdomain, serverdomain)
# Allow clientdomain to perform binder IPC to serverdomain.
define(`binder_call', `
# Call the server domain and optionally transfer references to it.
allow $1 $2:binder { call transfer };
# Allow the serverdomain to transfer references to the client on the reply.
allow $2 $1:binder transfer;
# Receive and use open files from the server.
allow $1 $2:fd use;
')

#####################################
# app_domain(domain)
# Allow a base set of permissions required for all apps.
define(`app_domain', `
typeattribute $1 appdomain;
# Label ashmem objects with our own unique type.
tmpfs_domain($1)
# Map with PROT_EXEC.
allow $1 $1_tmpfs:file execute;
neverallow { $1 -shell } { domain -$1 }:file no_rw_file_perms;
neverallow { appdomain -shell -$1 } $1:file no_rw_file_perms;
')

注意:在Android P版本中,系统严格限制了untrusted_app对于HIDL服务的访问权限,通过app_domain(application)定义的application,在通过hal_client_domain(application, hal_issue)成为hal_issue_client的client时与系统的never_allow冲突,解决方法是将需要访问HIDL服务的APK使用Android系统签名,同时设置platform_app对HIDL的访问权限

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值