Mem、Null、Zero、Full 与 Kmsg 设备
1. Major 1分发表
mem.c注册MEM_MAJOR=1。统一memory_open()按minor从devlist[]选择fops:
| Minor | Node | 行为 |
|---|---|---|
| 1 | /dev/mem |
物理地址空间 |
| 3 | /dev/null |
read EOF,write丢弃 |
| 4 | /dev/port |
I/O port,条件构建 |
| 5 | /dev/zero |
read零,mmap匿名零页 |
| 7 | /dev/full |
read零,write -ENOSPC |
| 8 | /dev/random |
CRNG接口 |
| 9 | /dev/urandom |
CRNG接口 |
| 11 | /dev/kmsg |
内核日志 |
设备由mem_class创建;mode通过devnode callback设置。
2. /dev/null
- read立即返回0;
- write返回输入长度;
- splice/write_iter同样消费数据;
- poll通常始终可读/写。
它不分配或保存payload。
3. /dev/zero
Read将用户buffer清零;mmap提供零填充匿名内存语义。大read循环中需处理signal和调度,避免长期占用CPU。
Write只丢弃数据,与/dev/null类似。
4. /dev/full
Read行为类似zero;任何write返回-ENOSPC。用于测试应用磁盘满错误路径。
5. /dev/mem
Offset代表物理地址。Read/write先通过架构hook验证区域,再使用xlate_dev_mem_ptr()等映射。
关键限制:
CONFIG_DEVMEM决定node是否存在;CONFIG_STRICT_DEVMEM/devmem_is_allowed()限制RAM和敏感区域;- architecture可拒绝访问;
- cache属性必须匹配物理区域;
- mmap由
phys_mem_access_prot()等决定page protection。
CAP_SYS_RAWIO和node权限仍不能使错误映射安全。
6. RK3588 /dev/mem风险
直接写GRF/CRU/PMU/IOC可能:
- 绕过regmap锁和write-mask;
- 关闭clock/power;
-破坏pinmux和电压域; - 与driver并发修改;
-暴露secure/保留内存; - 绕过设备所有权。
产品应禁用或严格限制DEVMEM;调试也应优先使用driver/debugfs。
7. /dev/port
只适用于ISA/PCI I/O port架构。ARM64 RK3588通常没有x86式port I/O,DEVPORT依赖ISA或PCI但实际架构支持仍需核对。
它与MMIO /dev/mem不是同一地址空间。
8. /dev/kmsg
由kmsg_fops提供:
- read内核log record;
- write注入用户消息到printk ring;
- poll等待新record;
- llseek支持定位/清晰语义。
读取和写入权限会泄露内核地址、设备信息或允许日志欺骗。dmesg_restrict、LSM和node mode应配合。
9. Init
chr_dev_init():
1 | register_chrdev(MEM_MAJOR) |
若某个device_create失败会继续创建其它node,启动日志需检查部分失败。
10. 容器边界
Device namespace不会天然虚拟化/dev/mem或/dev/kmsg。将宿主node映射进容器等于扩大宿主攻击面。
正在加载留言…