提示: 系统端提供Data分区upgrade目录创建-实现OTA功能接口-授权SELinux权限
文章目录
- 前言-需求-知识点
- 一、参考资料
- 二、修改文件
- 三、实现方案
-
- [1、系统创建data分区下 /data/upgrade 目录并授权](#1、系统创建data分区下 /data/upgrade 目录并授权)
- [2、创建 一个全新的文件类型标签- 新增ota_upgrade_file.te](#2、创建 一个全新的文件类型标签- 新增ota_upgrade_file.te)
- [3、在` system_app.te `文件中新增的两条 `SELinux `权限授予语句。](#3、在
system_app.te文件中新增的两条SELinux权限授予语句。) - [4、配置是在 file_contexts 文件中添加的一条文件上下文标注规则](#4、配置是在 file_contexts 文件中添加的一条文件上下文标注规则)
- 四、需求实战经验分享
-
- [App 具备系统签名-具备android.uid.system 配置 仍然没有权限](#App 具备系统签名-具备android.uid.system 配置 仍然没有权限)
- 总结
前言-需求-知识点
前言-需求
这里目标就是提供一个OTA接口,ota接口系统本身就有,看是否适配;接口同时会用到目录,比如把OTA升级文件放到哪里,这里放在 /data/upgrade 目录。


涉及知识点
这里简要说明涉及到的必备知识点,必须掌握的
- 系统起来后创建
/data/upgrade目录并授权权限 - 调通、验证 系统提供的升级接口
RecoverySystem类的RecoverySystem.installPackage(context,file);方法 - 授权
/data/upgrade目录的SELinux 权限
对于升级接口我们这里暂不讨论,这里我们重点讨论总结整理 SELinux 权限问题。
强烈建议: 做这个需求,几个特别基础的知识点一定要掌握:分区知识、SELinux 权限、init.rc 初始化文件、system.ui 知识点
一、参考资料
系统拷贝文件到data分区-/data/system目录-实战拷贝资源到vendor分区
这里重点需要参考的就是 Data分区相关知识点,Data分区是一个比较特殊的分区,在系统起来后再回创建,要搞清楚 Data分区和其它分区的区别和联系。

二、修改文件
java
system/core/rootdir/init.rc
device/mediatek/sepolicy/bsp/non_plat/ota_upgrade_file.te [新增文件]
device/mediatek/sepolicy/bsp/non_plat/file_contexts
device/mediatek/sepolicy/bsp/non_plat/system_app.te
三、实现方案
1、系统创建data分区下 /data/upgrade 目录并授权
路径:system/core/rootdir/init.rc
java
on post-fs-data
...............
mkdir /data/upgrade 0771 system system
chmod 0771 /data/upgrade
chown system system /data/upgrade
2、创建 一个全新的文件类型标签- 新增ota_upgrade_file.te
路径:device/mediatek/sepolicy/bsp/non_plat/ota_upgrade_file.te ,文件内容如下:
java
type ota_upgrade_file, file_type, data_file_type;
3、在system_app.te文件中新增的两条 SELinux 权限授予语句。
路径:device/mediatek/sepolicy/bsp/non_plat/system_app.te
它们的作用是:允许 system_app 这个域(Domain)对之前定义的 ota_upgrade_file 标签下的目录和文件执行一系列特定的操作
java
# for yl project to ota
allow system_app ota_upgrade_file:dir { open read search write add_name create remove_name rmdir };
allow system_app ota_upgrade_file:file { open read write create setattr unlink };
对目录的权限
java
allow system_app ota_upgrade_file:dir { open read search write add_name create remove_name rmdir };
这意味着 system_app 进程被允许对这个 ota_upgrade_file 目录做以下事情:
- 导航与读取:
open、read、search可以进入这个目录,列出它下面有什么文件。 - 写入内容:
write、add_name、create可以在该目录下创建新的文件或子目录。 - 删除内容:
remove_name可以删除该目录下的文件条目(即删除里面的东西,但不删除目录本身)。 - 删除目录:
rmdir可以删除这个空目录。 - 设置属性:
setattr虽然这条里没列出来,但在文件权限中会有,可以理解为修改目录的属性。
对文件的权限
java
allow system_app ota_upgrade_file:file { open read write create setattr unlink };
这意味着 system_app 进程被允许对这个 ota_upgrade_file 目录下的具体文件做以下事情:
-
基本读写:
open、read、write可以打开文件、读取文件内容、写入数据到文件(用于下载或写入OTA包)。 -
生命周期管理:
create、unlink可以创建新文件(用于保存OTA包);可以删除文件(升级完成后清理临时文件)。 -
权限修改:setattr 可以修改文件的属性(例如权限、所有者,用于确保文件可读可写)。
注意:这里没有 execute 权限。这意味着 system_app 可以读写这个文件,但不能直接运行它。这是符合安全预期的,OTA升级包通常只是被读取校验或解压,而不是作为程序执行。
为什么需要这两条规则
在添加这两条规则之前,即使 ota_upgrade_file 标签已经存在,SELinux 默认策略也会阻止 system_app 去访问它。
当你新增这两条规则后,就相当于明确地告知系统:
我允许系统级应用(system_app)去管理 OTA 升级的文件夹和文件,可以在里面新建、读写和删除 OTA 升级包,但仅限于此,不允许它执行里面的任何东西。
4、配置是在 file_contexts 文件中添加的一条文件上下文标注规则
路径:device/mediatek/sepolicy/bsp/non_plat/file_contexts
新增修改内容:
java
# for yl project to ota
/data/upgrade(/.*)? u:object_r:ota_upgrade_file:s0
在 file_contexts 文件中添加的一条文件上下文标注规则。它的作用是将 路径 与 SELinux 标签 绑定起来。
-
简单来说:
这句话的意思是:告诉
SELinux,当系统启动或重新打标签时,如果看到/data/upgrade这个路径下的文件,就给它们贴上ota_upgrade_file这个标签。 -
小结:
这行配置的核心作用就是贴标签。它告诉系统:所有在
/data/upgrade目录下(包括子目录)的东西,都给我贴上ota_upgrade_file的标签,这样之前允许的权限才能正确生效。
四、需求实战经验分享
App 具备系统签名-具备android.uid.system 配置 仍然没有权限
这里两种情况可以对比看:
- 客户本身是系统
App、具备系统签名、具备android.uid.system配置,但是还是无法把文件下载到/data/upgrade目录。报错java.io.IOException: Permission denied错误 - 但是如果你在
Framework层的各种服务Service里面操作是不会报错的。
分析:那是系统的服务都在SystemServer 进程里面,都是OK,自带各种权限的,即使你是系统App 也是没有访问权限的,错误如下:

总结
- 重点核心是搞清楚
SELinux权限问题,会有。 做多了就会有相关经验 简单了,第一次接触会很懵逼。 - 分区知识点
Data分区知识点,基本技能。