在 Linux 内核的完整性保护机制 IMA(Integrity Measurement Architecture)中,ima_read_file
和 ima_post_read_file
是两个关键钩子函数,用于在文件读取的不同阶段执行完整性验证。以下是它们的对比分析:
1. 核心区别
特性 | ima_read_file |
ima_post_read_file |
---|---|---|
触发时机 | 文件打开时(读取元数据阶段) | 文件内容加载到内存后(如 execve 、mmap ) |
验证目标 | 文件元数据(如 inode、扩展属性) | 文件实际内容(二进制/数据) |
典型场景 | 文件元数据篡改检测 | 内存执行/映射前的运行时完整性检查 |
依赖条件 | 需要文件已打开但未读取内容 | 需要文件内容已完整读取到内存 |
2. 代码实现分析
(1) ima_read_file
- 调用路径 :
open()
→vfs_open()
→ima_read_file
- 作用 :
验证文件元数据完整性(如 SELinux 上下文、文件哈希预注册值)。 - 失败行为 :
返回-EACCES
,阻止文件进一步操作。
(2) ima_post_read_file
-
调用路径 :
kernel_read_file()
→ima_post_read_file
-
作用 :
验证已加载到内存的文件内容完整性(如计算并比对哈希值)。
-
失败行为 :
内核模块加载场景中会触发
panic()
,防止恶意代码驻留内存。
3. 典型应用场景
(1) ima_read_file
的触发场景
- 文件打开 (
open
系统调用) - 文件元数据查询 (如
stat
) - SELinux 上下文检查
(2) ima_post_read_file
的触发场景
-
可执行文件加载 (
execve
) -
内核模块加载 (
insmod
/modprobe
) -
固件加载 (
request_firmware
) -
内存映射文件 (
mmap
)
4. 策略配置影响
-
ima_read_file
受
ima_policy
中func=FILE_CHECK
规则控制,例如: -
ima_post_read_file
由
func=MODULE_CHECK
、FIRMWARE_CHECK
或KEXEC_KERNEL_CHECK
等规则控制:
5. 安全影响对比
攻击类型 | ima_read_file 防御效果 |
ima_post_read_file 防御效果 |
---|---|---|
元数据篡改 | ✅(阻止打开) | ❌(已绕过) |
内容替换(Race条件) | ❌(仅检查初始状态) | ✅(内存运行时验证) |
恶意固件/模块加载 | ❌ | ✅(加载时阻断) |
6. 性能开销
-
ima_read_file
低开销(元数据校验,通常仅一次哈希计算)。
-
ima_post_read_file
高开销(需计算完整内容哈希,大文件可能影响性能)。
总结
ima_read_file
是 静态防御层,确保文件初始状态可信。ima_post_read_file
是 动态防御层,防止运行时内容篡改(如 TOCTOU 攻击)。- 协同工作模式 :
文件需先通过ima_read_file
验证才能进入读取流程,内容加载后由ima_post_read_file
二次验证,形成纵深防御。