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 文件安全工程可以拆成四条相互咬合的主线。第一条是分区布局:传统分区把 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 版本、是否 A/B、是否动态分区、是否解锁 Bootloader。
- 读取分区表:通过
ls -l /dev/block/by-name/与cat /proc/partitions确认分区命名与大小。 - 查看挂载状态:用
mount或cat /proc/mounts确认每个分区的文件系统、挂载点与读写属性。 - 检查权限与上下文:用
ls -lZ查看目标文件的 UID、GID 与 SELinux 标签。 - 验证完整性:确认 dm-verity 是否启用、vbmeta 是否禁用校验,判断修改是否可行。
- 实施改动并回归:改动后重新校验启动链,确认设备可正常启动且数据未泄露。
# 典型基线采集命令
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 文件安全工程的核心能力。接下来的章节,将逐一拆解这四个问题背后的机制与工具。