超越 fork()+exec():Linux 核心「Spawn Template」提案解析
LWN.net · 2026-06-05
Li Chen 在 Linux 核心郵件列表提出「spawn templates」機制,旨在取代 Unix 數十年來以 fork() + exec() 建立行程的模型。提案核心概念是讓使用者空間預先描述新行程的屬性(訊號遮罩、檔案描述符映射、命名空間等),再由核心一次性原子建立,避免現有模型的 fork 後、exec 前的危險視窗。
原本的問題
傳統 fork()+exec() 在 fork 後子行程短暫繼承父行程的所有資源,必須靠 close-on-exec、訊號處理、CLOEXEC 等機制手動清理。此期間若有多執行緒環境,fork 只複製呼叫執行緒,導致 mutex 死結風險(async-signal-safe 問題)。glibc 的 posix_spawn 已嘗試封裝此流程,但底層仍是 fork+exec,無法解決根本問題。
規格細節
spawn templates 提案引入新的核心物件:使用者空間先透過 spawn_template_create() 建立一個 template,描述新行程的 FD 映射、訊號配置、命名空間,再呼叫 spawn(template, path, argv, envp) 讓核心一步完成行程建立,跳過 fork 的全量複製。
提案以 io_uring 的 sqe 風格為靈感,以結構體批次描述操作而非一連串系統呼叫。FD 繼承清單可明確列出哪些 FD 要傳入新行程,其餘預設關閉,反轉目前 close-on-exec 的預設語義(白名單而非黑名單)。命名空間參數允許直接從 template 建立新的 user/net/mount namespace,簡化容器執行時的實作。
影響範圍
此提案若合入核心,對 container runtime(runc、containerd)、語言 runtime(Python subprocess、Go os/exec、Rust Command)影響深遠。目前提案尚在 RFC 階段,核心社群對 API 設計有爭議,特別是 template 物件的生命週期管理方式。LWN 文章顯示討論熱度高,後續進展值得追蹤。
vmsplice() 面臨移除:長達十年的安全問題與 LLM 新發現的漏洞
LWN.net · 2026-06-04
Linux 核心開發者正在討論移除 vmsplice() 系統呼叫,理由是該呼叫自 2008 年引入以來安全事件不斷,且近期 LLM 輔助審計工具又發現新的利用向量,使維護成本遠超實際使用量。
漏洞機制
vmsplice() 設計目的是讓使用者空間頁面零複製地送入 pipe,但其「將使用者頁面直接映射進核心 pipe buffer」的語義天然引發提權問題。2008 年 CVE-2008-0009/0010 便是透過 vmsplice 越權寫入 root 擁有的記憶體達成本機提權;同年 CVE-2008-0600 在數週內被大量野外利用。此後每隔數年都有新的相關 CVE 出現。
近期有開發者使用 LLM 對核心系統呼叫介面進行靜態分析,在 vmsplice 的 iov 處理路徑中找到新的邊界條件,進一步強化了移除的論據。splice() 本身的語義(pipe-to-pipe 或 pipe-to-fd)相對安全,被視為可保留的替代品。
受影響版本
vmsplice() 存在於所有主流 Linux 發行版。實際使用者極少:搜索主要 codebase 顯示主要只有 GLib 舊版的 pipe 傳輸路徑與少數效能實驗程式碼使用它。Linus Torvalds 在討論串中表示對移除持開放態度,但需要確認是否有 userspace ABI 穩定性顧慮。
修補與緩解
正式移除須等待核心版本確定;在此之前,seccomp 過濾器可封鎖 vmsplice syscall(syscall number 278 on x86-64)。容器環境(Docker 預設 seccomp profile、gVisor)通常已封鎖此呼叫。splice() 的零複製語義在大多數場景仍可替代 vmsplice,且不涉及使用者頁面的直接核心映射。
Josh:Rust 跨倉庫程式碼管理的代數過濾器方法
Inside Rust Blog · 2026-06-04
Rust 官方 Inside Rust 部落格在 2026-06-04 發文,介紹 Josh(Just One Single History)如何解決 Cargo、Clippy、Miri、Rust Analyzer 等工具與主倉庫 rust-lang/rust 之間的雙向同步問題。Josh 以 Rust 撰寫,對 git 倉庫執行可逆的代數過濾操作,取代舊有的 git subtree 工作流。
原本的問題
Rust 的工具鏈工具各自擁有獨立的 GitHub 倉庫,但整合進 rustc 的 CI 必須在單一 commit 上測試。舊有做法以 git subtree 定期從各工具倉拉入更新,但 subtree 的歷史線性化會讓 blame 難以追蹤,且雙向 push 容易產生合併衝突。當編譯器 API 變動需要跨倉庫同步修改時,多倉庫的 PR 協調尤為困難。
採用的方法
Josh 的核心是「代數過濾器(algebraic filters)」:每個過濾操作(prefix、exclude、glob 等)都有明確的逆操作,因此可雙向套用於 git DAG 而不失去歷史資訊。josh-sync 工具封裝 pull 與 push 操作:
- pull:從子倉庫取得 commit,以過濾器映射到主倉庫對應路徑,生成合法 git commit
- push:從主倉庫取出路徑子樹,以逆過濾器反向映射為子倉庫 commit,可直接推送
GitHub Actions workflow 每日自動觸發同步,失敗時通知 Zulip 頻道請人工介入。git blame 可直接追溯到原始子倉庫的 PR,這是 git subtree 做不到的。
影響範圍
對於任何以 monorepo 管理核心但允許工具倉獨立 release 的專案,Josh 提供了一個有正式逆操作保證的同步模型,而非依賴 ad-hoc 腳本。Josh server 本身以 HTTP API 提供過濾服務,可部署為共用基礎設施。目前 Rust 的 josh-sync 已開源,可作為模板直接複用。