为何编译devmem2.c生成的程序仅能读取物理内存而无法写入?
这是个很常见的权限与系统安全机制相关问题,我来帮你拆解可能的原因和解决办法:
1. 缺少CAP_SYS_RAWIO特殊权限
Linux下直接对物理内存(通过/dev/mem设备)执行写入操作,需要进程拥有CAP_SYS_RAWIO能力——这个权限允许进程绕过普通用户权限检查,直接操作硬件相关的敏感资源。
你可以先验证系统自带的devmem2是否被赋予了这个能力:
getcap /usr/bin/devmem2
如果输出类似/usr/bin/devmem2 = cap_sys_rawio+ep,就说明它确实拥有该权限。而你自己编译的test程序默认没有这个能力,因此只能完成读取(部分场景下读取/dev/mem不需要该权限),无法执行写入。
解决方法:给你的程序添加这个特殊权限:
sudo setcap cap_sys_rawio+ep ./test
添加后再运行./test尝试写入,应该就能正常工作了。
2. SELinux/AppArmor安全模块限制
如果你的系统开启了SELinux或者AppArmor这类强制访问控制模块,它们可能会阻止自定义程序对/dev/mem执行写入操作,哪怕你已经给程序添加了CAP_SYS_RAWIO权限。
你可以临时关闭SELinux测试(注意:生产环境不建议长期关闭):
sudo setenforce 0
如果关闭后程序能正常写入,那就是SELinux的规则限制了。你可以选择:
- 将程序放到系统默认允许的路径(比如
/usr/bin)并重新设置cap权限 - 编写自定义SELinux规则,允许你的程序访问
/dev/mem
3. 编译选项的细微差异
虽然这个可能性比前两个小,但也值得检查:部分版本的devmem2源码依赖特定编译宏才能启用完整功能。你可以尝试用gcc(更贴合C程序编译)加上宏定义重新编译:
gcc -D_GNU_SOURCE devmem2.c -o test
编译完成后再按方法1添加权限测试。
内容的提问来源于stack exchange,提问作者L.KID




