#14688·gvisor

`runsc` 的 OCI seccomp 转换器默默地丢弃了每个规则的 `errnoRet`, 从而打破了标准的 clone3/glibc ENOSYS 回退模式。

作者: ghaskins创建于 2026年9月10日更新于 2026年9月12日
标签type: bug

说明

□ 总结

runsc/ specutils/seccomp/seccomp.go' 将 OCI LinuxSeccomp' 简介转换成 a BPF方案读取了规则的名称'、行动'和Args',但从未读取 LinuxSeccomp Rule.ErrnoRet' (或LinuxSeccomp.Default ErrnoRet')。 每个 SCMP ACT ERRNO ' 结果硬编码为`EPERM':

开始 // runc/ specutils/seccomp/seccomp.go (英语). var (英语: 杀死 Thread Action = seccomp. 杀死线索 陷阱动作=秒码。 陷阱 // runc 总是返回 EPERM 作为 SECCOMP RET ERRNO 的错误代码 错误动作 = seccomp. returnError.Code(int16(unix.EPERM)) // runc 总是返回 EPERM 作为 SECCOMP RET TRACE 的错误代码 跟踪动作=秒接. Trace.Code( uint16( unix. EPERM) ). 允许动作=秒comp. 允许 (中文(简体) ).

func 转换 Action( act specs.LinuxSeccomp Action) (seccomp. Action, 错误) { 切换动作{ . . . . . . . . 实例。 动作Errno : 返回错误操作, 无 / 总是 EPERM —— 从未查阅错误编辑 . . . . . . . . {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


`改变规则() ' 重复`s.syscalls',只读`syscalls'。 行动`,
赞美。 阿格斯,还有"无声" 名称 -- -- " 旁听 " 。 ErrnoRet 从未在任何地方被贬低
在包裹。 这不是最近出现的倒退:`错误行动'/`追踪行动'
恒定日期到原始承诺 添加 OCI 分包支持
(`dcd532e2e',2020-09-16),从未读过习惯错误.

正确做到这一点的机制已经存在,并已发挥作用——`Set ReturnCode'/`.Code ()'
使用任何“int16”,而哨兵对过滤应用程序的任意错误表示尊重。
通过`seccomp(SECCOMP SET MODE FILTER,.)'自行安装——确认为反对
`pkg/sentry/内核/seccomp.':

开始
实例 :
/ “返回值的下十六位元中的结果”
// 用户土地作为错误 而不执行系统调用。"
t.Arch (). 返回(- intptr( 结果. Data ()))

由现有的“间接试验”行使。 RetErrno Returns Errno ' 试验,它声称 非 EPERM 错误( " ENOTNAM " ) 为自动安装过滤器而正确往返。 差距 具体在OCI- spec → BPF * 转换器 * 中,而不是哨兵本身的秒码中 执行。

□ 为什么这很重要:它打破了标准的 Clone3/glibc 兼容模式

glibc \ 2. 34 尝试 “ clone3 ” 先在“ pthread create” 中进行“ clone3 ” ( 和其他进程/ 线程创建) ** 只有在Clone3' 与ENOSYS ' 失败时,才适用。 具体来说,任何其他错误都被视为难以挽回的失败。 (sysdeps/unix/sysv/linux/clone-internal.c'). 因为Clone3'的单一论点是: 用于“ struct Clone args” 的不透明指针, 经典的 seccomp- BPF 无法通过标记过滤它 。 方法 “ clone( ) ” 的 scalar ` flags' 参数可以过滤—— 因此任何 OCI 分集配置 需要专门阻断“clone3(CLONE NEWUSER)”的 线程/ 进程创建工作有效) 别无选择,只能直接屏蔽 syscall 和 依靠“ENOSYS”来保存被仍然可过滤的“克罗内()”的克罗内克回落 电话

这恰恰是装有容器的Docker 和被glibc 2.34 采用时的收发筒 . . . . . . .