如何通过 logcat 查看 SELinux 拒绝日志并定位权限问题?

解读

国内 Android 面试中,SELinux 拒绝日志是系统安全与稳定性面试的高频考点。面试官不仅想看候选人“会不会敲命令”,更关注“能否把拒绝日志翻译成业务风险、能否给出最小化放行方案、能否在发版前验证”。因此,回答要体现“日志抓取 → 日志解读 → 策略定制 → 闭环验证”的完整思路,并兼顾国内 ROM 定制(如 MIUI、ColorOS、HarmonyOS 兼容层)与 GMS 环境差异。

知识点

  1. SELinux 模式:Disabled、Permissive、Enforcing;国内用户版 ROM 强制 Enforcing,eng/userdebug 可临时 setenforce 0。
  2. 拒绝日志格式:avc: denied { 操作 } for pid=xxx comm="xxx" name="xxx" dev="xxx" ino=xxx scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=文件类型 permissive=0。
  3. 关键字段:scontext(主体)、tcontext(客体)、tclass(客体类别)、{ 操作 }(权限位)。
  4. 国内常用抓取命令:adb logcat | grep avc、adb shell dmesg | grep avc、audit2allow 工具链(AOSP prebuilts 或 Linux 环境)。
  5. 策略来源:
    • AOSP system/sepolicy:平台基线,不可直接修改;
    • 设备厂商 sepolicy:device/xxx/sepolicy,国内项目常闭源,需通过 odm/etc/selinux 动态更新;
    • 应用沙箱策略:无法修改,只能规避。
  6. 国内合规要求:工信部 164 号文要求系统升级不得降低安全强度,禁止用户侧关闭 SELinux;因此面试必须强调“最小权限、不放宽主体类型”。
  7. 验证手段:audit2allow 生成 .te → mmm 编译 sepolicy → 刷机或热更新 → 复现场景 → 二次抓 log 确认无 avc denied。

答案

步骤一:抓取拒绝日志

  1. 复现场景,保持设备 Enforcing:
    adb shell getenforce # 确保返回 Enforcing
  2. 清空旧日志,聚焦复现:
    adb logcat -c
    adb logcat -b all | grep "avc: denied" > avc.txt
    若日志被冲掉,可同步抓取 kernel 环形缓冲区:
    adb shell dmesg -w | grep avc >> avc.txt

步骤二:解读日志
示例日志:
avc: denied { read write } for pid=1234 comm="camera.daemon" name="tof_sensor" dev="sysfs" ino=12345 scontext=u:r:hal_camera_default:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0
结论:hal_camera_default 主体对 sysfs 类型的 file 缺少 read write 权限。

步骤三:快速定位业务模块
根据 scontext=u:r:hal_camera_default 可知属于 camera HAL;结合 comm="camera.daemon" 与 dev="sysfs" 可推断访问 /sys/class/tof/tof_sensor/enable。

步骤四:评估风险与方案选择
国内项目需先确认:

  • 该节点是否已在设备厂商白名单;
  • 是否可通过改变访问路径(如迁移到 /vendor 自定义 sysfs)规避;
  • 若必须放行,遵循“最小权限、最小主体”原则,不直接给 hal_camera_default 添加 sysfs 全部权限,而是:
    1. 定义新类型 sysfs_tof_sensor,关联文件上下文;
    2. 仅允许 hal_camera_default 对该类型 { read write };
    3. 提交 patch 至设备厂商 sepolicy 仓库,走内部安全评审。

步骤五:生成并验证策略
在 AOSP 根目录:
audit2allow -i avc.txt -M camera_tof
输出 camera_tof.te:
allow hal_camera_default sysfs_tof_sensor:file { read write };
将 .te 放入 device/xxx/sepolicy/vendor/hal_camera.te,同步新增 file_contexts:
/sys/devices/platform/tof/tof_sensor(/.*)? u:object_r:sysfs_tof_sensor:s0
全编 sepolicy:
m sepolicy
刷入设备,复现场景后再次抓取 logcat,确认无新的 avc denied 且功能正常。

步骤六:上线前检查
使用 sediff 对比新旧 sepolicy,确保仅新增最小规则;
通过 CTS/STS 与厂商安全扫描,避免引入 neverallow 违规(国内 CTS 不过无法入网)。

拓展思考

  1. 国内 ROM 的“权限白名单”机制:部分厂商在 fwk 层拦截 ioctl,即使 SELinux 放行仍返回 EPERM,需联合查看 logcat 中的“E/SELinuxPermission”与“E/QCamera”等标签,避免误判为 SELinux 问题。
  2. 动态 sepolicy 更新:Android 13 支持 Mainline 模块,国内厂商通过 odm/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 实现热更新,面试可提“无需整包升级即可修复拒绝日志”,体现对国内 OTA 节奏的理解。
  3. 与用户隐私的冲突:若拒绝日志涉及 /data/misc/userid,直接放行可能违反《个人信息保护法》,需转用系统服务代理访问,体现“安全合规优先”意识。