Linux 6.9 悄悄讓 LUKS 睡眠鎖碼失效,兩年後才被 git bisect 抓到
Mathstodon(Ingo Blechschmidt)· 2026-07-02
德國數學家兼 Debian 使用者 Ingo Blechschmidt 在 Mastodon 貼文中揭露一個潛伏超過兩年的資安迴歸:自 Linux 6.9(2024 年 5 月釋出)起,筆電進入睡眠時用來清除 LUKS 磁碟加密金鑰的機制其實已經悄悄失效。他形容這是一場「有趣又要命」的除錯過程,最後靠 git bisect 才把問題釘死在特定版本上。這代表任何相信「蓋上筆電就等於保護資料」的使用者,過去兩年其實都暴露在風險中。
問題發現
Blechschmidt 平常使用全磁碟加密(LUKS)搭配 Debian 的 cryptsetup-suspend 附加元件,這套機制的設計是:筆電睡眠前執行 cryptsetup luksSuspend,把磁碟加密金鑰從記憶體中抹除,恢復時再要求輸入密碼重新載入金鑰。問題在於恢復時雖然照樣要求輸入密碼,金鑰卻其實從未真正被清空,只是使用者被要求重新輸入密碼,營造出「安全機制有運作」的假象。他透過反覆比對 kernel 版本,才發現這個假象已經存在兩年多。他也點出一個更普遍的現象:「一個由可信作者提出、難以驗證、又和已知正確論證很相似的技術論證,幾乎不會被人仔細檢查」——程式碼也是一樣的道理。
技術細節
金鑰為何沒被清掉,關鍵出在 Linux 的 keyring(金鑰環)子系統。cryptsetup 依賴 thread-keyring(7) manpage 的一項承諾:執行緒(thread)結束時,掛在該執行緒上的 keyring 會被系統自動銷毀。cryptsetup 正是利用這個特性,把金鑰暫時放進一個用完即丟的執行緒 keyring,藉此避免金鑰長期停留在核心記憶體裡。但從 6.9 開始,某次 device-mapper/block 層的重構意外打破了這個保證,使得原本應該隨執行緒消失的 keyring 得以繼續存活,金鑰也就一路留在核心記憶體中不會被清除。這個問題後來被整理進 cryptsetup 專案的一份合併請求,其中列出三種金鑰可能殘留在 keyring 裡的情境,第三種正是這個核心層級的迴歸:即使只是最基本的 luksOpen 接著 luksSuspend,在 6.9 之後的核心上也不會真的清除金鑰。
# 使用者原本以為安全的流程
cryptsetup luksOpen /dev/sdaX mydisk
# 睡眠前
cryptsetup luksSuspend mydisk
# 6.9 之後:金鑰其實仍留在核心 keyring 中後續影響
這個迴歸主要衝擊的是 Debian 系發行版與其衍生版本上,特意啟用 cryptsetup-suspend 這類「睡眠即上鎖」流程的使用者,一般預設不會清空睡眠金鑰的系統則不受影響,因為使用者本來就沒對睡眠狀態抱持這種期待。真正讓人不安的是這個機制被信任了兩年多,卻從未真正做到它宣稱的事。NixOS 專案後來加了一個回歸測試來捕捉這類問題,相關修正也被整理進一個 NixOS 的 pull request,方便用 git bisect 精準定位是哪一次核心重構造成的破壞。cryptsetup 專案目前提出的因應方向,是在偵測到金鑰無法被清除時主動跳出警告,而不是像現在一樣靜默失敗,讓使用者誤以為自己是安全的。
原始來源:Ingo Blechschmidt 的 Mastodon 貼文、cryptsetup GitLab MR !936
卡在 0.9.x 十五年的 LMDB,悄悄升上 1.0
LMDB 官方文件站(lmdb.tech)/ GitHub 版本庫 · 2026-06-30
由 Symas 的 Howard Chu 為 OpenLDAP 打造的嵌入式資料庫 Lightning Memory-Mapped Database(LMDB),從 2011 年首次釋出以來版本號一直卡在 0.9.x,最新的 0.9.35 也才在今年一月釋出。就在 2026/06/30,專案在 GitHub 版本庫悄悄打上 LMDB_1.0.0 標籤,結束了長達十五年的「零點九」時代。整份 CHANGES 檔案裡對這個里程碑的說明極其精簡,只留下一行「Many fixes/enhancements」。
從 0.9 到 1.0,這十五年在做什麼
LMDB 的設計最早在 2009 年於 OpenLDAP 開發者郵件論壇提出,目的是取代當時 OpenLDAP 依賴的 Berkeley DB,其原型甚至源自 OpenBSD ldapd 專案的一個實作。它的核心概念是把整個資料庫檔案透過 mmap() 映射進處理序的位址空間,讓讀取操作幾乎等同直接存取記憶體,不需要額外的快取層或反序列化開銷。資料結構採用 B+ 樹,寫入時採用 copy-on-write(寫入時複製)而非傳統的預寫日誌(WAL),配合多版本並行控制(MVCC),讓寫入交易不會阻塞讀取者,讀取者也不會阻塞寫入者。這套設計讓 LMDB 長期是 OpenLDAP、Bitcoin Core、多個機器學習框架資料管線背後常見的儲存引擎選擇。
為什麼版本號意義重大
對長期使用 LMDB 的專案來說,卡在 0.9.x 十五年其實是一種穩定訊號:它意味著磁碟格式、API 與 ABI 在這段期間幾乎沒有破壞性變動,任何依賴它的系統都能安心升級小版本。正式跳到 1.0.0 通常被視為專案對其穩定性與成熟度的正式背書,而不只是版號的數字遊戲。從 GitHub 標籤紀錄看,1.0.0 是先在今年四月底切出 LMDB_1.0.0-branch 分支,經過約兩個月的打磨後才在 06/30 正式定案,中間也穿插了 0.9.34、0.9.35 兩個維護版本,顯示團隊是刻意把 1.0 分支和既有穩定版並行維護,而非直接砍掉重練。
社群觀察
由於 LMDB 的官方 GitHub 版本庫標明是「唯讀鏡像」,正式的問題回報與討論仍走 OpenLDAP 自家的 ITS(Issue Tracking System),這也是為什麼外界很難在 GitHub 上看到完整的變更說明。簡短到近乎沒有內容的 changelog,反而成了社群討論這次發布時最常被提起的細節,不少開發者在看到版本號跳動時的第一反應是「這專案居然還在維護」,畢竟多數人對 LMDB 的印象仍停留在十年前那個穩定但低調的 0.9 系列。無論如何,對於任何把 LMDB 嵌進生產環境的專案而言,這都是值得盯著看的版本邊界。
Debian 老將花上百小時,只為把 LLM 寫的程式碼擋在相依套件外
Joey Hess 部落格(joeyh.name)· 2026-07-02
知名 Debian/Haskell 開發者 Joey Hess(git-annex 作者)在部落格文章中透露,他花了大約 100 小時,只為了確保 git-annex 建置流程不會依賴任何含有 LLM 生成程式碼的套件。這不是一次性的檢查,而是他持續在做、而且越來越吃力的稽核工作。文章發布於 7 月 2 日午後,語氣少見地疲憊。
稽核中發現了什麼
Hess 在逐一檢視 git-annex 的相依套件時,撞見幾種讓他印象深刻的異常模式。其中一個套件出現一份長達 1489 行、內容語意混亂的 commit 訊息,卻對應著在一個約 26000 行的程式庫裡改動了將近 10000 行程式碼,改動規模與說明品質完全不成比例,讓人很難判斷這些變更究竟做了什麼、為什麼要做。另一個案例是有人直接把 LLM 用來「抄」其他專案程式碼的提示詞留在紀錄裡,內容遊走在著作權侵犯的邊緣,只是還沒真的踩過線。他也提到看過大幅度的 LLM 改動後來又被整包還原,卻沒有人解釋為什麼一開始要做、後來又為何撤銷。
一次讓他退出協作的事件
文章裡提到一個具體案例:某個他曾參與的專案裡,有貢獻者用近似「Add fourmolu config and restyled neat format a module」這樣的提示詞讓 LLM 產生格式調整,然後直接 commit 進去,還自稱是「10x 工程師」。Hess 因此停止了與該專案的進一步協作,他在文中直接對這類開發者喊話:請多想想這麼做的更廣泛影響,而不只是省下自己的時間。這類「格式調整」看似無害,卻代表審查者必須花時間確認 LLM 到底有沒有動到邏輯,而不能單純信任一份格式化 diff。
為何他覺得這場仗打不贏
Hess 自嘲「大概已經在螳臂擋車」,但仍持續稽核下去,因為他覺得對使用者、對下游專案有責任。他點名像 Software Freedom Conservancy 這樣的大型自由軟體組織,在 LLM 生成程式碼這個議題上實質上選擇了不表態,這讓他質疑繼續留在某些社群裡的意義。他的困境很具體:稽核相依套件的人力成本呈線性甚至更快成長,但生成這些程式碼的成本卻趨近於零,兩邊的速度完全不對稱。文章沒有提出解方,更多是把一個維護者實際承受的稽核負擔攤在陽光下,讓讀者自己判斷這個趨勢會走向哪裡。