解决 系统升级后Selinux的file_context指定的目录或者文件域变成unlabeled

本文记录了一次SELinux权限丢失的问题排查过程,详细分析了导致系统分区中SELinux属性丢失的原因,并给出了修复建议。

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

最近遇到一个selinux相关问题,相关的denied打印如下:

avc: denied { write } for name="/" dev="mmcblk0pxx" ino=2 scontext=u:r:AAAA:s0 tcontext=u:object_r:unlabeled:s0 tclass=dir permissive=0

avc: denied { create } for pid=1886 comm="xxxxx" name=aaa" scontext=u:AAAA:s0 tcontext=u:object_r:unlabeled:s0 tclass=file permissive=0

之前指定的/aaa/bbb目录下的文件域为XXX_XXX突然全部变成unlabeled。


unlabeled的标签是系统没有指定的目录就是unlabeled。尝试把出现的denied规则加到te文件里?too yong to naive.

Google能随随便便让进程去建unlabeled ?在external/sepolicydomain.te文件中有如下neverallow规则:

# Do not allow any domain other than init or recovery to create unlabeled files.
neverallow { domain -init -recovery } unlabeled:dir_file_class_set create;

凡是过CTS的娃娃都应该明白这意味着什么,不能随便加!而且neverallow 规则不能修改,否则CTS会有fail项。

Google不让改怎么办?问Google吧!

Google到相关的资料都指向一个原因:系统可能做过OAT升级到时系统分区被破坏,selinux属性丢失

https://marc.info/?l=seandroid-list&m=142072965016559&w=2


咨询了报问题的同事,出问题的机器没有做过OAT升级/(ㄒoㄒ)/~~。但是还是怀疑和分区被破坏有关系。

接着分析:

1.拷贝出来板子的/file_contexts文件,发现指定/aaa/bbb目录的域确实是XXX_XXX。

2.实验把/aaa/bbb目录指定为CCC_CCC重新烧boot.img发现域还是没有改变。

使用命令restorecon -r /aaa/bbb指定的CCC_CCC域起作用,此时怀疑系统有备份file_contexts的属性到某个地方。

3.紧接着查到系统里有把file_contexts的指定设置到系统的分区镜像里。用dd命令拷贝出来/dev/block/分区镜像。查看多了unlabeled的字段。


最后联想到最近有同事做数据保护工作。咨询了同事在/aaa/bbb分区因为写数据掉电或者其他情况被破坏掉后,他会使用make_ext4fs重新格式化分区,但是格式化话后没有回复selinux的域指定。而系统在升级时不会去升级/aaa/bbb分区,系统每次起来都会读一句坏了的分区中保存的/file_contexts。导致出现u:object_r:unlabeled:s0 问题。


解决方法是在数据保护格式化分区后重新调用一次selinux_android_restorecon方法回复selinux属性。

关于selinux_android_restorecon 参考文章:http://blog.youkuaiyun.com/l173864930/article/details/17232547




<think>我们正在讨论SELinux策略文件中的file.te和file_contexts文件(注意:用户可能误写为file_context.te,但实际标准名称是file_contexts)。根据引用内容,我们可以总结如下: 引用[1]提到: - file_contexts:给所有的自定义变量赋具体的值(包括文件节点、设备节点、可执行程序) - file.te:声明file_contexts中为文件类型的变量 引用[2]和[3]则提供了关于进程域和可执行文件标签的示例。 引用[4]提到,一般不需要直接修改system/sepolicy中的文件,而是添加设备专用政策文件(位于/device/manufacturer/device-name/sepolicy目录中)。 因此,用户的问题是关于SELinux策略中file.te和file_contexts文件的作用与解释。 下面我将详细解释这两个文件: ### 1. **file.te** 文件 - **作用**:在SELinux策略中,`file.te`文件用于**声明文件类型(file types)**。这些类型用于对系统中的文件、目录、设备节点等进行分类,以便在策略规则中引用。 - **内容格式**:在`file.te`中,我们使用`type`语句来定义新的文件类型。例如: ```te type my_custom_file_type, file_type; ``` 这里: - `my_custom_file_type` 是自定义的类型名称。 - `file_type` 表示这是一个文件类型(属于属性`file_type`)。 还可以定义其他与文件相关的类型,如: - 目录类型:`type my_custom_dir_type, file_type, fs_type;` - 设备节点类型:在`device.te`中定义(如引用[1]中所示),但`file.te`通常只关注普通文件和目录。 - **关联性**:在`file.te`中定义的类型,会在`file_contexts`文件中被赋予具体的文件路径。 ### 2. **file_contexts** 文件 - **作用**:将文件路径与SELinux类型(在`.te`文件中定义的类型)关联起来,即**给文件系统对象打标签(labeling)**。这样,当系统启动或文件被创建时,SELinux会根据这个文件给相应的文件系统对象赋予安全上下文。 - **内容格式**:每一行包含一个文件路径模式和一个安全上下文。例如: ``` /system/bin/tinymix u:object_r:tinymix_exec:s0 ``` 这里: - `/system/bin/tinymix` 是文件路径(支持正则表达式)。 - `u:object_r:tinymix_exec:s0` 是安全上下文,其中`tinymix_exec`就是在`.te`文件中定义的类型。 另一个例子(来自引用[1]): ``` /dev/GT9762AF(/.*)? u:object_r:GT9762AF_device:s0 ``` 这表示`/dev/GT9762AF`及其子节点都被赋予类型`GT9762AF_device`。 - **应用时机**:这些标签通常在以下情况下被应用: - 系统启动时(由`init`进程在挂载文件系统后通过`restorecon`或`setfiles`命令设置)。 - 创建新文件时(如果父目录有默认的SELinux上下文,则新文件会继承)。 - 手动执行`restorecon`命令时。 ### 3. 两个文件的协同工作流程 1. **声明类型**:在`file.te`(或`device.te`等)中定义一个新的类型(例如`my_file_type`)。 2. **关联路径**:在`file_contexts`文件中,将文件路径模式与这个类型关联。 3. **策略规则**:在进程的`.te`文件中,通过`allow`规则允许该进程访问此类型。例如: ```te allow my_process my_file_type:file { read write }; ``` ### 4. 示例解析(基于引用[1]和[3]) - **添加设备节点**(引用[1]): - 在`device.te`中声明设备节点类型:`type GT9762AF_device, dev_type;` - 在`file_contexts`中关联设备节点路径:`/dev/GT9762AF(/.*)? u:object_r:GT9762AF_device:s0` - 在进程的`.te`文件(如`factory.te`)中添加访问权限:`allow factory GT9762AF_device:chr_file { read write ioctl open };` - **添加可执行文件**(引用[3]): - 在`file.te`(或自定义的`tinymix.te`)中声明可执行文件类型: ```te type tinymix, domain; type tinymix_exec, exec_type, file_type; ``` - 在`file_contexts`中关联可执行文件路径:假设路径为`/system/bin/tinymix`,则: ``` /system/bin/tinymix u:object_r:tinymix_exec:s0 ``` - 在`tinymix.te`中定义进程域转换(由`init`启动): ```te init_daemon_domain(tinymix) ``` 并添加必要的权限规则。 ### 5. 注意事项 - **文件位置**:在AOSP中,设备特定的策略文件应放在设备的`/device/manufacturer/device-name/sepolicy`目录下(引用[4]),而不是直接修改`system/sepolicy`。 - **标签继承**:对于由`init`启动的进程,其标签要么在`init.rc`中用`seclabel`指定,要么通过`init_daemon_domain`宏进行域转换(引用[2])。 ### 总结 | 文件 | 主要作用 | 内容示例 | |------------------|------------------------------|---------------------------------------| | `file.te` | 声明文件、目录等类型 | `type my_file_type, file_type;` | | `file_contexts` | 将文件路径映射到SELinux类型 | `/path/to/file u:object_r:my_file_type:s0` | 这两个文件是SELinux策略中定义文件安全上下文的基础,通过它们可以实现对文件访问的精确控制。 --- ### 相关问题 1. 如何在Android设备上添加一个新的SELinux策略文件? 2. SELinux中进程域转换是如何工作的(例如`init_daemon_domain`)? 3. 如何调试SELinux权限拒绝(denial)问题? 4. 在SELinux策略中,`allow`规则的语法和常见用法有哪些? 5. 设备节点和普通文件在SELinux策略中有什么区别?</think>### SELinux 策略文件解析:`file.te` 与 `file_contexts` 在 SELinux 策略开发中,`file.te` 和 `file_contexts` 是两个关键配置文件,它们协同工作实现对文件系统对象的安全标签管理。以下是详细解释: --- ### 1. **`file.te` 文件** **作用**:声明文件类型(File Types),定义文件系统对象的 **安全类型标识符**。 **核心功能**: - 为文件、目录、设备节点等资源创建唯一的 SELinux 类型标签 - 将类型归类到预定义属性(如 `file_type`, `dev_type`) - 作为策略规则(`allow` 语句)中的目标类型 **典型内容格式**: ```te # 声明普通文件类型 type my_custom_file, file_type; # 声明设备节点类型 type my_device_node, dev_type; # 声明可执行文件类型 type my_executable, exec_type, file_type; ``` **示例场景**(引用[1][3]): ```te type tinymix_exec, exec_type, file_type; // 声明 tinymix 可执行文件的类型 type GT9762AF_device, dev_type; // 声明设备节点类型 ``` --- ### 2. **`file_contexts` 文件** **作用**:将 **文件系统路径** 映射到 `file.te` 中定义的安全类型,实现 **标签绑定**。 **核心功能**: - 为具体文件/目录分配 SELinux 安全上下文 - 支持正则表达式匹配路径模式 - 在系统启动或文件创建时自动应用标签 **典型内容格式**: ```context # 路径模式 安全上下文 /dev/my_device.* u:object_r:my_device_node:s0 /system/bin/tool u:object_r:my_executable:s0 /data/app/.* u:object_r:app_data_file:s0 ``` **示例场景**(引用[1][3]): ```context /dev/GT9762AF(/.*)? u:object_r:GT9762AF_device:s0 // 设备节点标签绑定 /system/bin/tinymix u:object_r:tinymix_exec:s0 // 可执行文件标签绑定 ``` --- ### 3. **协同工作流程** 1. **类型声明**(`file.te`) 定义类型 `my_file_type` 和 `my_device_type`。 2. **路径映射**(`file_contexts`) 将 `/path/to/file` 绑定到 `my_file_type`,`/dev/my_device` 绑定到 `my_device_type`。 3. **策略控制**(`*.te`) 在进程策略中授权访问: ```te allow my_process my_file_type:file { read write }; allow my_daemon my_device_type:chr_file { ioctl open }; ``` **完整示例**(引用[1][3]): ```te // file.te type GT9762AF_device, dev_type; // file_contexts /dev/GT9762AF(/.*)? u:object_r:GT9762AF_device:s0 // mediaserver.te allow mediaserver GT9762AF_device:chr_file { read write ioctl open }; ``` --- ### 4. **关键差异总结 | 特性 | `file.te` | `file_contexts` | |--------------------|--------------------------------------|--------------------------------------| | **目的** | 声明类型和属性 | 绑定路径到类型 | | **内容** | SELinux 类型定义语句 (`type ...`) | 路径-上下文映射规则 | | **作用阶段** | 策略编译时 | 文件系统创建/启动时 | | **修改影响** | 需重新编译策略 | 需运行 `restorecon` 或重启 | | **正则支持** | 否 | 是 | --- ### 5. **实践注意事项** 1. **自定义策略位置**(引用[4]): 设备专属策略应放在 `/device/<厂商>/<设备名>/sepolicy/`,而非修改系统全局策略。 2. **标签继承机制**(引用[2]): `init` 启动的进程通过 `init_daemon_domain()` 宏转换域上下文,例如: ```te init_daemon_domain(tinymix) // 将 tinymix 从 init 域切换到专属域 ``` 3. **验证工具**: - `ls -Z` 查看文件当前标签 - `restorecon -v /path` 强制重新应用标签 - `sepolicy-check` 验证策略一致性 > 📌 完整开发流程参考 [SELinux for Android](https://source.android.com/security/selinux)[^4]。 --- ### 相关问题 1. 如何为 Android 新增设备节点添加 SELinux 权限? 2. `init_daemon_domain()` 宏的具体工作原理是什么? 3. 如何调试 SELinux 权限拒绝(avc: denied)问题? 4. 普通文件与设备节点在策略定义上有何区别? 5. 如何自定义进程的 SELinux 安全域?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值