seccomp异常排查与修复指南
seccomp异常时的维测
遇到 seccomp(Secure Computing Mode)异常 时,通常表现为进程因违反 seccomp 规则而被内核终止(常见信号 SIGSYS
或 SIGKILL
),日志中会有相关记录。以下是系统的维测步骤和关键点:
1. 确认异常现象
日志定位:
- 检查系统日志(
/var/log/syslog
、/var/log/messages
或journalctl
):1
2journalctl -k --grep="seccomp"
grep -i "seccomp" /var/log/syslog - 典型日志示例:
1
audit: type=1326 ... syscall=xxx ... seccomp=action=KILL ...
- 检查系统日志(
进程信号:
- 若进程崩溃,用
dmesg
或journalctl
检查是否因SIGSYS
(非法系统调用)终止。
- 若进程崩溃,用
2. 获取触发的系统调用信息
从日志提取关键字段:
syscall=
:触发的系统调用号(如231
代表exit_group
)。arch=
:CPU 架构(如x86_64
)。exe=
:触发进程的路径。
系统调用号转名称:
1
2# 根据架构查询(x86_64 示例)
ausyscall x86_64 231 # 输出:exit_group
3. 分析 seccomp 策略
定位策略来源:
容器环境(如 Docker):
1
docker inspect <容器ID> --format='{{.HostConfig.SeccompProfile}}'
默认策略路径:
/etc/docker/seccomp/*.json
。自定义应用:
检查代码中加载的 seccomp BPF 策略(如通过libseccomp
或prctl(PR_SET_SECCOMP)
)。
策略规则检查:
- 确认触发的系统调用是否被显式禁止(
SCMP_ACT_KILL
、SCMP_ACT_ERRNO
)。 - 检查是否有规则覆盖了该调用(如基于参数过滤)。
- 确认触发的系统调用是否被显式禁止(
4. 动态调试:使用跟踪工具
strace 捕获系统调用:
1
strace -f -e trace=all -s 512 -o strace.log <命令>
过滤触发前的调用序列,定位非法调用。
perf 监控 seccomp 事件:
1
2perf record -e 'syscalls:sys_enter_seccomp' -ag
perf scriptauditd 高级跟踪:
1
auditctl -a always,exit -F arch=b64 -S <syscall> # 监控特定调用
5. 临时绕过与测试
禁用 seccomp 验证:
- 容器运行时添加参数(临时测试):
1
docker run --security-opt seccomp=unconfined ...
- 注意:仅用于定位问题,生产环境勿用!
- 容器运行时添加参数(临时测试):
修改策略允许调用:
在 seccomp 配置文件中添加规则:1
2
3
4{
"names": ["被禁止的系统调用名"],
"action": "SCMP_ACT_ALLOW"
}
6. 深入代码分析
反汇编定位调用点:
- 使用
gdb
附加进程,捕获SIGSYS
信号:1
2
3gdb -p <PID>
(gdb) catch signal SIGSYS
(gdb) continue - 信号触发时检查寄存器:
$RAX
:系统调用号。$RIP
:调用指令地址。
- 使用
检查调用栈:
1
(gdb) bt full
7. 常见陷阱
- 架构差异:32位/64位调用号不同(如
open
vsopenat
)。 - 隐式调用:
glibc
封装函数可能触发非预期调用(如内存分配调用mmap
)。 - 参数过滤:策略中基于参数过滤规则(如
open
的O_RDWR
被禁止)。
8. 修复与验证
策略调整:
- 允许必要调用,或放宽参数限制。
- 使用
SCMP_ACT_LOG
记录调用而不终止进程(调试模式)。
策略热重载:
1
2# 动态更新策略(需程序支持)
syscallerctl --reload-seccomp <策略文件>
总结排查流程
1 | graph TD |
通过以上步骤,可高效定位 seccomp 违规根源。关键点:结合内核日志、动态跟踪与策略分析,优先在测试环境复现问题。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Helloeuler!