1. 课程导入

Android 设备从按下电源键到进入桌面,背后经历了一条高度工程化的启动链:BootROM 加载引导程序,引导程序校验并挂载 boot 分区,内核启动后挂载 system、vendor、product 等只读分区,最终由 init 拉起 zygote 与系统服务。这条链路上的每一个分区、每一次挂载、每一份文件权限,都直接决定了设备的安全边界。本课程要解决的,正是"分区是什么、文件放在哪、权限怎么控、数据如何不被窃取或篡改"这四个层层递进的问题。

一、学习目标:从"看得懂"到"改得动、守得住"

本课程不是单纯的分区名词罗列,而是围绕"识别—分析—验证—加固"的工程闭环展开。完成学习后,你应当能够达到以下目标:

  • 识别层:能准确说出 A/B 分区、动态分区、super 分区、vbmeta 等关键分区的职责与相互关系,读懂 fstab 与 Android.bp 中的分区配置。
  • 分析层:能通过 adb shell、mount、ls -lZ 等命令定位文件归属、SELinux 上下文与挂载属性。
  • 验证层:能理解 dm-verity、AVB 校验链、文件级加密(FBE)的验证逻辑,并判断一次修改是否会破坏启动完整性。
  • 加固层:能针对应用私有目录、共享存储、系统只读分区设计合理的访问控制与数据保护方案。
核心判断标准:一个 Android 文件安全工程师的水平,不体现在能刷多少包,而体现在能否在改动前预判"这次改动会不会让设备无法启动、会不会让数据暴露"。

二、核心概念:分区、挂载、权限、校验四条主线

Android 文件安全工程可以拆成四条相互咬合的主线。第一条是分区布局:传统分区把 boot、system、vendor 各自独立烧录,而动态分区把 system、vendor、product 打包进一个 super 分区,由 liblp 在运行时切分,A/B 分区则让 slot_a 与 slot_b 互为备份,实现无缝升级。

第二条是挂载与文件系统:ext4、f2fs、erofs 各有取舍,只读分区常用 erofs 压缩节省空间,/data 则用 f2fs 兼顾性能与寿命。挂载参数中的 ro、noatime、nodev 不是装饰,而是攻击面收敛手段。

第三条是权限与 SELinux:Linux 的 rwx 位决定"谁能读写",SELinux 的 domain:type:class 决定"哪个进程能碰哪类文件"。二者叠加,才构成 Android 的强制访问控制。

第四条是完整性与加密:dm-verity 用哈希树保证只读分区未被篡改,AVB 用签名链保证引导镜像可信,FBE 用密钥保证 /data 中每个应用目录彼此隔离。

Android 系统分区与文件安全工程 · 知识框架 启动与校验链 BootROM Bootloader vbmeta / AVB boot / init_boot init → zygote system_server ① 分区布局 • boot / init_boot • system / vendor / product • super(动态分区) • slot_a / slot_b(A/B) • userdata / metadata • vbmeta / dtbo / pvmfw ② 挂载与文件系统 • ext4 / f2fs / erofs • fstab 与 mount 参数 • ro / noatime / nodev • /data 加密挂载 • overlayfs 与 GSI • 挂载命名空间隔离 ③ 权限与 SELinux • UID / GID / rwx • file_contexts 标签 • domain / type / class • neverallow 规则 • 应用沙箱与私有目录 • 共享存储 Scoped Storage ④ 完整性与加密 • dm-verity 哈希树 • AVB 签名链 • FBE 文件级加密 • Keymaster / KeyMint • Metadata 加密 • 防回滚 rollback index 实战路线图:识别 → 分析 → 验证 → 加固 识别 读分区表 / fstab 分析 查权限 / 上下文 验证 验哈希 / 签名 / 加密 加固 收敛权限 / 保护数据

三、方法流程:一次分区与文件安全分析的通用步骤

面对一台陌生设备或一个安全需求,建议按固定流程推进,避免"上来就改"导致设备变砖。以下流程适用于排查、审计与加固三类任务:

  1. 建立基线:记录设备型号、Android 版本、是否 A/B、是否动态分区、是否解锁 Bootloader。
  2. 读取分区表:通过 ls -l /dev/block/by-name/ 与 cat /proc/partitions 确认分区命名与大小。
  3. 查看挂载状态:用 mount 或 cat /proc/mounts 确认每个分区的文件系统、挂载点与读写属性。
  4. 检查权限与上下文:用 ls -lZ 查看目标文件的 UID、GID 与 SELinux 标签。
  5. 验证完整性:确认 dm-verity 是否启用、vbmeta 是否禁用校验,判断修改是否可行。
  6. 实施改动并回归:改动后重新校验启动链,确认设备可正常启动且数据未泄露。
# 典型基线采集命令
adb shell getprop ro.build.version.release
adb shell getprop ro.boot.slot_suffix
adb shell ls -l /dev/block/by-name/
adb shell cat /proc/mounts | grep -E "system|vendor|data"
adb shell ls -lZ /data/data/com.example.app/
adb shell getprop ro.boot.veritymode

四、案例与场景:三个真实问题引出课程主线

场景一:应用私有数据被其他应用读取。某应用把敏感配置写入外部存储 /sdcard/,结果被同设备其他应用扫描获取。根因是未使用应用私有目录 /data/data/<包名>/,也未启用 Scoped Storage。这对应"权限与 SELinux"主线。

场景二:修改 system 分区后设备无法启动。开发者直接 adb remount 后替换了 system 中的文件,重启后卡在开机动画。根因是 dm-verity 哈希树校验失败,且未同步更新 vbmeta。这对应"完整性与加密"主线。

场景三:OTA 升级后旧分区残留导致异常。A/B 设备升级到 slot_b 后,slot_a 仍保留旧版本,某些引导参数未同步,导致回滚时行为不一致。这对应"分区布局"与"挂载"主线。

常见误区:把 adb root 当成万能钥匙。实际上,即使拥有 root,SELinux 仍可能拒绝访问;即使 SELinux 放行,dm-verity 仍可能让只读分区无法持久修改。三层限制必须同时考虑。

五、课程知识框架与关键对象速查

下表汇总本课程将反复使用的核心对象,建议在后续章节中随时对照:

对象 所在位置 核心作用 安全关注点
boot / init_boot 独立分区 内核与 init 第一阶段 AVB 签名、防篡改
super 动态分区容器 承载 system/vendor/product lpmetadata 完整性
vbmeta 独立分区 存放 AVB 校验元数据 禁用校验会破坏信任链
/data userdata 分区 应用数据与用户文件 FBE 加密、目录隔离
file_contexts system 分区 定义文件 SELinux 标签 标签错误导致拒绝访问
fstab.<硬件> vendor / boot 定义挂载参数 ro/nodev 等收敛项

六、复盘:本课程的学习节奏建议

本课程共 30 章,整体按"概念—机制—工具—实战—排障"推进。前段建立分区与文件系统的基本认知,中段深入 SELinux、dm-verity、AVB、FBE 等安全机制,后段通过真实场景完成审计、加固与故障定位。学习时建议每章都动手执行一次命令,把"看到的路径"变成"验证过的结论"。

入门阶段最重要的习惯:任何修改前先备份分区镜像,任何结论前先用命令验证。分区与文件安全没有"大概应该没问题",只有"已验证通过"。

当你能够独立回答"这个文件属于哪个分区、被哪个进程以什么身份访问、是否受完整性保护、数据是否加密"这四个问题时,就已经具备了 Android 文件安全工程的核心能力。接下来的章节,将逐一拆解这四个问题背后的机制与工具。