WinReg 函式庫案例:Claude 抓出的「零長度字串」漏洞其實不存在
Giovanni Dicanio's Blog · 2026-07-28
Giovanni Dicanio 在 2026 年 7 月 28 日發表文章,記錄他用 Claude 對自己維護的開源 C++ 函式庫 WinReg 做程式碼審查的過程。WinReg 是一套把 Windows Registry API 包裝成物件導向介面的函式庫,Claude 在審查 RegKey 類別時回報一個看似嚴重的漏洞:讀取空字串登錄值會讓程式當機。Dicanio 重新檢查後發現,這個回報其實不成立。
背景
Windows 讀取登錄檔字串值有兩種呼叫慣例。舊式的 RegQueryValueEx 不保證回傳的緩衝區一定有 NUL 結尾字元;較新的 RegGetValueW(Windows Vista 起提供)則保證一定會補上終止字元,就算登錄檔裡實際儲存的原始資料缺少結尾符號也一樣。WinReg 的字串類 getter 全部走後者。
核心改動/規格細節
Claude 指出的問題聚焦在這行程式碼:
result.resize((dataSize / sizeof(wchar_t)) - 1);Claude 的推論是:若 dataSize == 0,無號整數相減會下溢成 SIZE_MAX,resize() 收到這麼大的長度會丟出 std::length_error 例外。Claude 也提到,同一個類別裡的二進位資料 getter 在對應情境下都有做 dataSize == 0 的防呆檢查,唯獨 GetStringValue、GetExpandStringValue、TryGetStringValue、TryGetExpandStringValue 這四個字串 getter 沒有,看起來像是遺漏。
影響範圍
Dicanio 指出這四個字串 getter 內部都是透過 RegGetValueW 讀取登錄值,而不是 RegQueryValueEx。由於 RegGetValueW 保證回傳字串一定有 NUL 結尾,dataSize 在這四個函式裡永遠不可能是 0——它至少會包含一個結尾字元的長度,因此 Claude 描述的下溢情境在這份程式碼裡不會發生。二進位 getter 之所以需要額外檢查 dataSize == 0,是因為它們讀的是不受 NUL 結尾保證約束的原始位元組,兩者的防呆邏輯本來就不必相同。
Larry Hastings 釋出 Blanket 1.0:把 Python 多執行緒測試變成可重現的決定性流程
GitHub – larryhastings/blanket · 2026-05-14(v1.0)
CPython 核心開發者 Larry Hastings(Argument Clinic 作者、Python 3.4/3.5 版本經理)在 2026 年 PyCon US 上發表 Blanket 專案並釋出 1.0 版,原始碼公開於 GitHub。這套工具讓測試作者能直接操控 Python 執行緒排程器的執行順序,取代原本由作業系統決定、跑一次換一種結果的隨機排程。
背景
多執行緒程式的競爭條件,長期以來難以寫成穩定的測試,因為哪個執行緒先跑、何時被切換是作業系統排程器決定的,同一份測試碼跑十次可能有十種結果。這個問題在 free-threaded Python(PEP 703,自 3.13 起可關閉 GIL)出現後更加明顯:過去被 GIL 隱性序列化掩蓋的競爭條件,現在會真的並行觸發,讓原本穩定通過的測試變得時好時壞。
核心改動/規格細節
Blanket 不重新實作同步原語,而是包裝真正的 threading 物件:Lock、RLock、Condition、Semaphore、BoundedSemaphore、Event、Barrier 這七種原語都被包了一層,實際加解鎖仍交給原本的 threading 實作處理。每次方法呼叫都會變成一個 transaction,在 BLOCKED、WAITING、COMMITTED、RETURNED 等狀態間前進,由主執行緒扮演的排程器決定每個 transaction 何時往下走。
import blanket
scenario = blanket.Scenario()
lock = scenario.Lock()
def worker(name):
with lock:
print(f"worker {name} got the lock")
with scenario:
threads = [scenario.thread(worker, args=(n,)) for n in ('A', 'B', 'C')]影響範圍
Blanket 需要 Python 3.7 以上,依賴 big 函式庫,若要使用位元組碼注入功能來為既有無鎖程式碼插入排程檢查點,還需額外安裝 bytecode 模組。與 Rust 的 Loom、Shuttle 或 JVM 的 Lincheck 這類靠窮舉所有執行緒交錯來找 bug 的模型檢查工具不同,Blanket 讓測試作者手動指定特定的執行順序,適合把已知的競爭條件釘成回歸測試,或針對只在特定交錯下才會走到的例外分支做完整覆蓋率。
Grml 2026.09 發布:換裝 Linux 7.1.8 核心,新增 exFAT USB 開機支援
grml.org 官方 changelog · 2026-09-03
Grml 專案在 2026 年 9 月 3 日發布代號「Hättiwaritätti」的 2026.09 版本。Grml 是一套以 Debian 為基礎、鎖定系統管理員使用情境的 Live Linux 發行版,本次以即將發布的 Debian 14(forky)套件為基礎重建,並把核心升級到 Linux 7.1.8。
核心改動/規格細節
- initramfs 加入 exFAT 支援,USB 隨身碟若採用 exFAT 格式也能直接開機,先前僅支援 FAT 系列與 NTFS/ext
- GNU Screen 升級到
5.0.1,設定檔格式有不相容變更,需改用新設定檔或改回screenrc_v4才能沿用舊設定 - 建置系統 grml-live 現在需要 Linux user namespaces 才能運作,同時移除了對 32 位元 i386 的支援與舊版設定檔讀取方式
- grml-debootstrap 新增可選擇建置 Debian forky 的選項
影響範圍
套件清單新增 3cpio、ovmf(amd64)、qemu-efi-aarch64、pydf,移除 speedtest-cli、squashfs-tools、tpm-udev。grml2usb 在偵測到系統缺少 GRUB 相關套件時,現在會給出更明確的錯誤訊息,舊版的 save-config/restore-config 腳本也一併移除。這個版本總計修了 19 個 issue、合併 144 個 pull request;官方 changelog 也註明因建置系統改版,2026 年 6 月 10 日到 9 月 2 日之間沒有產出每日構建版本。