4. AAOS中的设备节点管理:/dev目录结构、权限控制与SELinux策略

在AAOS(Android Automotive OS)中,设备节点是用户空间与内核驱动交互的核心通道。与标准Linux或普通Android不同,AAOS对设备节点的管理引入了更严格的权限分层和SELinux强制访问控制,以确保车载系统的安全隔离与稳定运行。本章将深入剖析AAOS下/dev目录的组织结构、权限控制机制以及SELinux策略对设备节点访问的深层影响。

4.1 AAOS下/dev目录结构特点

AAOS的/dev目录在标准Linux基础上增加了大量与车载硬件相关的设备节点,主要分为以下几类:

设备类别 典型节点示例 功能描述
CAN总线设备 /dev/can0, /dev/can1 车辆控制器局域网通信接口
车载传感器 /dev/gnss, /dev/imu GPS/GNSS定位、惯性测量单元
音频通道 /dev/audio_hw, /dev/tfa98xx 车载音频DSP、功放控制
显示与触控 /dev/dri/card0, /dev/input/eventX 图形渲染、触摸屏输入
车辆诊断 /dev/diag, /dev/obd OBD-II诊断接口
安全关键设备 /dev/tee, /dev/trusty 可信执行环境通信

AAOS通过ueventd守护进程在系统启动时动态创建设备节点,其配置文件位于/ueventd.rc或/vendor/ueventd.rc。与标准Android相比,AAOS的ueventd.rc中增加了大量针对车载外设的mode、owner和group定义。

关键差异:AAOS中/dev目录下的车载设备节点默认权限通常为0660,所有者是system,所属组为system或特定硬件组(如can、gps),而非普通Linux中的root:root。这种设计限制了非系统级应用的直接访问。

4.2 权限控制机制:从内核到用户空间

AAOS对设备节点的权限控制分为三个层级,形成纵深防御体系:

  1. 内核级权限:通过ueventd.rc中的mode字段设置文件权限位(如0660),控制读/写/执行的基本访问。
  2. 用户/组隔离:将设备节点分配给特定AID(Android ID),如AID_SYSTEM、AID_CAN、AID_GPS。应用必须具有对应GID才能访问。
  3. 能力(Capability)约束:对需要特权的设备节点(如/dev/mem、/dev/kmem),AAOS通过capabilities机制进一步限制,即使进程以root运行也无法绕过。

实践建议:在AAOS驱动开发中,不要依赖chmod 777开放设备节点。正确的做法是在ueventd.rc中为设备节点分配专用GID,并在应用层通过android:sharedUserId或requestPermission获取对应组权限。

4.3 SELinux策略对设备节点的影响

SELinux是AAOS安全架构的核心,它基于强制访问控制(MAC)模型,对设备节点的访问施加了比传统DAC(自主访问控制)更严格的约束。即使进程拥有/dev/can0的0666权限,如果SELinux策略不允许,访问仍会被拒绝。

4.3.1 设备节点的SELinux上下文

每个设备节点在创建时都会被赋予一个SELinux安全上下文,格式为user:role:type:level。对于AAOS车载设备,常见的类型(type)包括:

设备节点类型 SELinux类型示例 说明
CAN设备 can_device 仅允许can_service域访问
GNSS设备 gnss_device 仅允许gnss_service域访问
音频设备 audio_device 仅允许audioserver域访问
诊断设备 diag_device 仅允许diag_service域访问
通用车载设备 vehicle_device 允许vehicle_hal域访问

4.3.2 SELinux策略规则示例

在AAOS的.te策略文件中,设备节点的访问规则通常如下:

# 允许can_service域打开并读写can_device类型的设备节点
allow can_service can_device:chr_file { open read write ioctl };

# 允许gnss_service域打开并读取gnss_device
allow gnss_service gnss_device:chr_file { open read ioctl };

# 禁止非授权域访问vehicle_device
neverallow { domain -vehicle_hal } vehicle_device:chr_file { open read write ioctl };

这些规则确保了只有特定的系统服务(如can_service、gnss_service)才能操作对应的硬件设备,第三方应用即使拥有文件权限也无法绕过SELinux检查。

4.4 设备节点访问流程与SELinux交互

下图展示了AAOS中一个应用或服务访问设备节点时,权限检查的完整流程:

AAOS设备节点访问权限检查流程 用户空间进程 DAC权限检查 (文件mode / uid/gid) SELinux MAC检查 (安全上下文匹配) Capability检查 (特权操作限制) 允许访问设备节点 拒绝访问 (avc: denied) 说明: AAOS中设备节点访问必须依次通过DAC、SELinux MAC和Capability三层检查。SELinux拒绝时会在内核日志中输出"avc: denied"信息, 这是调试设备节点权限问题的重要线索。

4.5 常见权限问题与调试方法

在AAOS驱动开发中,设备节点访问失败通常由以下原因导致:

问题现象 可能原因 调试命令/方法
open()返回-EACCES DAC权限不足(mode/owner错误) ls -lZ /dev/xxx 检查权限位和上下文
open()返回-EPERM SELinux策略拒绝 logcat -b events | grep avc 或 dmesg | grep avc
ioctl()返回-EACCES Capability不足或SELinux对ioctl的细粒度控制 ps -AZ | grep 进程名 检查进程安全上下文
设备节点未创建 ueventd.rc配置缺失或udev规则未生效 cat /proc/devices 确认驱动注册;检查ueventd.rc语法

重要提醒:在AAOS开发阶段,可以通过setenforce 0临时关闭SELinux来验证是否为策略问题,但严禁在产品车机上关闭SELinux。正确的做法是根据avc denial日志编写对应的.te策略文件,并编译进系统镜像。

4.6 自定义设备节点的SELinux策略编写

当在AAOS中添加新的车载硬件设备节点时,需要为其定义SELinux类型并编写访问规则。以下是标准步骤:

  1. 定义设备类型:在device/厂商/车型/sepolicy/目录下创建my_device.te文件:
type my_device, dev_type, mlstrustedobject;
# 声明该类型为设备节点类型,并允许MLS信任
  1. 为设备节点打标签:在file_contexts文件中添加:
/dev/my_device u:object_r:my_device:s0
  1. 授权访问域:在my_service.te中编写规则:
allow my_service my_device:chr_file { open read write ioctl };
  1. 编译并验证:重新编译bootimage,启动后通过ls -lZ /dev/my_device确认上下文正确。

最佳实践:AAOS推荐将车载设备节点的SELinux类型统一放在vehicle_device或vendor_device的命名空间下,便于策略管理和审计。避免使用unconfined_domain或init域直接访问硬件设备。

4.7 本章小结