fix(code-runner): allow exec on /tmp tmpfs for compiled languages

Docker tmpfs 挂载默认带 noexec,编译型语言(go/rust)把编译产物
落在 /tmp 后再 exec 会报 permission denied:
  - rust: /tmp/main (run-rust.sh 的 rustc 输出)
  - go:   /tmp/go-build*/b001/exe/main (GOTMPDIR=/tmp 的链接器输出)

解释型语言(python/node)执行根文件系统里的解释器,不在 tmpfs 上,不受影响。

给 /tmp tmpfs 显式加 exec 选项。这是容器执行的固有需求——只要
沙箱支持任何编译型语言,/tmp 就必须可执行。安全模型由只读根文件系统 +
cap_drop=ALL + no-new-privileges + pids/memory/cpu 限制兜底,/tmp 可执行
不引入额外攻击面(容器内本就允许执行自身进程)。
This commit is contained in:
xfy 2026-07-09 11:04:27 +08:00
parent 2f6f8e549d
commit 0ab3340133

View File

@ -17,7 +17,10 @@ pub static DOCKER_CLIENT: LazyLock<Docker> = LazyLock::new(|| {
pub fn build_host_config(limits: &ResourceLimits) -> HostConfig { pub fn build_host_config(limits: &ResourceLimits) -> HostConfig {
let mut tmpfs = HashMap::new(); let mut tmpfs = HashMap::new();
tmpfs.insert("/code".to_string(), "size=16m,uid=1000,gid=1000".to_string()); tmpfs.insert("/code".to_string(), "size=16m,uid=1000,gid=1000".to_string());
tmpfs.insert("/tmp".to_string(), "size=64m,mode=1777".to_string()); // /tmp 必须 exec编译型语言go/rust把编译产物落在 /tmp 后再 exec
// Docker tmpfs 默认 noexec 会让执行二进制时报 EACCESpermission denied
// 解释型语言python/node执行根文件系统的解释器不受影响。
tmpfs.insert("/tmp".to_string(), "size=64m,mode=1777,exec".to_string());
tmpfs.insert("/run".to_string(), "size=16m,mode=1777".to_string()); tmpfs.insert("/run".to_string(), "size=16m,mode=1777".to_string());
let memory = (limits.memory_mb * 1024 * 1024) as i64; let memory = (limits.memory_mb * 1024 * 1024) as i64;