字符设备安全、权限与故障排查
1. 攻击面
字符设备可直接承载:
- ioctl命令解析;
- user pointer;
- 任意长度buffer;
- MMIO/mmap;
- DMA;
-固件命令; - 密钥和随机数;
- power/reset;
- host/hypervisor输入。
Device node是内核攻击面的入口,不是普通文件。
2. 权限
组合使用:
- devtmpfs/udev mode和group;
- capability;
- SELinux/AppArmor;
- cgroup device policy;
- namespace设备映射;
- seccomp限制ioctl;
- module/Kconfig最小化。
不要依赖应用“不会调用危险ioctl”。
3. User Copy
原则:
- 先复制固定header;
- 验证version、size、count;
- 检查乘加溢出;
- 设全局上限;
- 再分配;
- 再复制payload;
- 输出结构先清零,防内核padding泄露。
TOCTOU敏感结构应一次复制到内核buffer,不反复读取user memory。
4. Ioctl ABI
稳定ABI应:
- 使用
__u32/__u64; - 避免裸pointer和
long; - 保留reserved字段;
- 明确endianness;
- 支持版本/size扩展;
- 实现compat;
- 未知flags返回错误。
5. Mmap
验证:
- offset/length;
- page alignment;
- overflow;
- resource范围;
- cache attributes;
- writable权限;
- VMA生命周期。
映射物理MMIO应要求明确capability,且不能越过设备resource。
6. DMA
用户提供长度、offset和descriptor时:
- pin/map页数上限;
- IOMMU;
- DMA direction;
- 同步;
- completion后才unmap;
- remove/reset取消DMA;
- 防止设备访问已释放user page。
7. Random和TPM
- 应用使用
getrandom()而非直接信任/dev/hwrng; - HWRNG quality需硬件依据;
- TPM node权限不能替代TPM policy;
- event log和PCR需联合验证;
- 不在日志中输出随机seed、密钥或TPM auth。
8. /dev/mem和kmsg
量产建议:
STRICT_DEVMEM;- 限制/关闭
DEVMEM; dmesg_restrict=1;- 控制
/dev/kmsg写; - 容器不映射;
- 禁止
/dev/mem作为正式驱动替代。
9. 基础排障
1 | cat /proc/devices |
确认:
- Kconfig;
- driver已注册;
- device probe成功;
- cdev/misc注册成功;
- devtmpfs/udev创建node;
- major/minor匹配;
- LSM/权限;
- open后的硬件状态。
10. Strace
1 | strace -yy -e openat,read,write,ioctl,mmap,poll ./app |
区分:
ENOENT:node不存在;ENODEV/ENXIO:driver/实例无效;EACCES/EPERM:权限;EAGAIN:nonblock无数据;ERESTARTSYS/EINTR:signal;ETIMEDOUT:硬件/协议;EFAULT:user pointer。
11. Dynamic Debug
1 | echo 'file drivers/char/* +p' > /sys/kernel/debug/dynamic_debug/control |
随机数、TPM和管理消息日志可能敏感,调试后关闭。
12. 产品裁剪
保留实际使用的mem/random/misc、Rockchip HWRNG和必要TPM transport;关闭AGP、PCMCIA、并口、IPMI、Xillybus和legacy平台驱动,除非硬件明确需要。
正在加载留言…