linux内核模块加载需cap_sys_module能力,非root用户须显式授权;权限检查在sys_init_module入口由may_init_module执行,早于模块解析,失败返回operation not permitted。

Linux 内核模块加载不是普通用户能随意触发的操作,权限控制是内核安全的第一道防线。只有具备特定能力(capability)的进程才能执行加载动作,否则系统会直接拒绝——这是硬性限制,无法绕过。
谁有资格加载模块?
内核通过 CAP_SYS_MODULE 能力判断权限,而非简单看是不是 root 用户。实际生效规则如下:
- root 用户默认拥有该能力,所以
sudo insmod通常能成功 - 非 root 用户若被显式授予该能力(如用
setcap cap_sys_module+ep /usr/bin/insmod),也可加载 - 容器环境或受限 shell 中,即使 UID 是 0,若未配置该 capability,
insmod仍会报Operation not permitted - SELinux 或 AppArmor 启用时,还会叠加策略检查,可能进一步拦截
权限检查发生在哪一步?
关键检查点在内核的 sys_init_module 系统调用入口,由 may_init_module() 函数执行。它不依赖模块内容,只查调用者上下文:
- 检查当前进程是否具备
CAP_SYS_MODULE - 若启用模块签名(
CONFIG_MODULE_SIG=y),还会验证签名有效性,失败则返回-EKEYREJECTED - 该检查早于任何内存分配或 ELF 解析,属于“第一关卡”
常见权限失败现象与排查
遇到加载失败,先别急着查模块格式,优先确认权限路径是否通畅:
-
insmod: ERROR: could not insert module xxx.ko: Operation not permitted→ 典型权限不足,不是模块问题 -
dmesg中出现module: Insufficient capabilities to load module→ 明确指向 capability 缺失 - 在 systemd-nspawn、Docker 容器中加载失败 → 需加
--cap-add=SYS_MODULE启动参数 - 使用
modprobe却提示权限错误 → 注意它底层仍调用sys_init_module,权限要求完全一致
绕过限制的合规方式
生产环境不建议禁用权限检查,但可通过以下方式合法放宽:
- 为可信工具单独授予权限:
sudo setcap cap_sys_module+ep /usr/local/bin/myloader - 在 initramfs 阶段加载模块:此时内核尚未启用完整 capability 检查,适合基础驱动
- 将模块编译进内核(built-in),彻底避开动态加载权限机制
- 使用
/etc/modules-load.d/配置开机自动加载:由 systemd 在特权上下文中执行,无需用户干预











