蔡秀吉 Hsiu-Chi Tsai

Open Source

上游系統工程

我追查分散式系統裡三類錯誤:資源用量算錯、物件的生命週期處理錯、並行時的競態。每找到一個,就做出能重現的案例與回歸測試,再把修正送進 Kubernetes、OpenTelemetry、Kueue 與其他上游專案。

CNCF Ambassador · Kubernetes v1.38 Release Team(Signal Shadow) · Nephio (LFN) TSC Member · OpenTelemetry GitHub Org Member · Zephyr M5Stack Platforms Maintainer

同一種錯誤常常不只出現在一個地方。我順著同一個成因往其他專案與程式路徑找,目前已追出四條跨專案的缺陷家族:

  1. 資源會計 int64 溢位 Kubernetes · Kueue · Volcano · KAI-Scheduler · CDI · KEDA 12 變體 · 11 merged
  2. DRA 跨廠商 result 守衛 NVIDIA · Intel · IBM · AMD · Google 9 driver · 8 org
  3. NTN SIB19 路徑交易性 OCUDU(srsRAN 後繼) 12 缺陷
  4. Kueue 配額會計驗證 kubernetes-sigs/kueue 7 缺陷

開源貢獻摘要

Merged
460 PRs
Upstreams
108 projects
End to end
116 found & fixed
Foundations
11

Representative campaigns

三條代表工作

三組工作的做法相同:找到一個錯誤之後,把它的成因寫成一條能拿去檢查別處的規則,再到同類的程式碼裡逐一核對;找到的問題都附上回歸測試,送回上游修正。

Resource accounting

跨專案追蹤資源會計不變量

起點是 Kubernetes DRA 裡的一個 int64 溢位。我把它歸納成一條檢查:資源的加總、相乘與型別轉換,不能溢位、截斷、漏算或重複扣款;再拿這條去看 Kueue、KAI-Scheduler、Volcano、CDI 等排程與配額的實作。Kubernetes 後來為 Quantity 的 int64 問題開了一份整理清單(#141166),這份清單底下另有 12 支修正合併。

Failure class
溢位、截斷、漏算、重複扣款、型別邊界
Method
不變量提取、邊界構造、跨專案 variant search
Outcome
12 變體、6 上游、11 修正合併
Evidence
每項附 issue、patch 與失效路徑回歸測試

Representative evidence

  1. kubernetes #140442拒絕無法表示的 consumable-capacity 請求(int64 溢位)
  2. kubernetes #140666擋掉無法使用的 validRange(除零)
  3. kueue #12897拒絕加總會溢位 int64 的 device counts
  4. kubernetes #141305Quantity 新增可判斷溢位的 accessor
  5. kueue #15026用量越過 int64 仍精確,不再撞上「無上限」的哨兵
閱讀完整變體分析

Async lifecycle

OpenTelemetry C++ 的非同步生命週期

OpenTelemetry C++ 送出遙測資料的路徑是非同步的,我依它該遵守的約定逐條檢查:連線關掉之後不能再碰它(否則就是 use-after-free)、等待完成的執行緒不能漏接通知或被誤喚醒、每一次送出要恰好結算一次,不能零次也不能兩次。

Failure class
use-after-free、lost wakeup、重複/零結算
Method
契約定義、失效路徑構造、race 下重現
Outcome
12 筆修正合併(至 2026-09-30)、含 race 回歸測試
Evidence
附最小重現與契約測試

Representative evidence

  1. opentelemetry-cpp #4289HttpServer 於連線關閉後仍寫 response(use-after-free)
  2. opentelemetry-cpp #4298ES exporter 無述詞等待致 lost-wakeup 永久阻塞
  3. opentelemetry-cpp #4363curl client 讓每次操作恰結算一次
  4. opentelemetry-cpp #4431一個 curl session 只送一個請求,重用不再毀掉執行中的 operation
  5. opentelemetry-cpp #4618curl operation 最後結果碼的資料競態(TSAN)
看 opentelemetry-cpp 合併紀錄

NTN transactionality

OCUDU NTN 更新路徑的交易性

5G 衛星網路(NTN)的基地台用 SIB19 廣播衛星的位置與時間參數。我把一次 SIB19 更新當成一筆交易來看:要嘛完整生效,要嘛完全不動。照這個標準看下來,十二個缺陷都在同一條路徑上:非同步程式拿著已經失效的資料、有界佇列滿了之後的處理、更新做到一半失敗卻沒有復原、失敗的回傳值被忽略、時間值繞回起點時算錯,以及系統資訊組裝器的狀態對不上。

Failure class
記憶體生命週期、時間與編號邊界、數值退化、錯誤處理與交易性、狀態不同步
Method
以「單筆交易」重述整條更新路徑
Outcome
12 缺陷分五類,3 個有修正合併(1 個只修一部分),7 個仍開
Evidence
含幾何邊界 sweep 與跨最佳化等級測試

Representative evidence

  1. ocudu !1097 (GitLab)eci_to_orbital 的 acos 引數浮點越界 → NaN 汙染整組軌道要素
  2. ocudu !1045R17 kmac-r17 CLI 邊界驗證(自報自修)
  3. ocudu !1047R17 taCommon 邊界驗證(自報自修)
閱讀完整 NTN 稽核

Security

安全修復

前三件是專案自己發了安全公告的漏洞,後一件是 Go 的 DHCP 函式庫 insomniacslk/dhcp 的遠端當機問題,我從修正根因一路做到下游專案升級。

已發佈且具名的 advisory

三則公告都在 credits 欄寫了我的名字。Istio 和 Volcano 是我私下回報、維護者修好後才公開的;Zephyr 那則是我先公開回報並送了修正,Zephyr 的安全團隊事後補發公告,也是三則裡唯一有 CVE 的。三則都已修正,但都還沒被 GitHub 的全域漏洞資料庫和 OSV 收錄。

ESP32 的 I2S 驅動對沒接線的方向解參考空指標,使用者執行緒能讓整個系統停機

開了 userspace 的 ESP32-C6 上,被授權使用 I2S 裝置的使用者執行緒,只要對沒接線的方向下一次觸發指令,核心就會讀取位址 0 而停機;影響只限可用性。我回報了 #115719 並寫了修正 #115721,公告列我為修正開發者。CVE-2026-19737 是 Zephyr 以 CVE 編號管理單位的身分自己發的,紀錄引用了這支修正,但沒有列出名字。評分 CVSS 5.5,修正會隨 4.5.0 發佈。

✓ Published

BackendTLSPolicy 在 CA 參照解不出來時,sidecar fail open 成明文

也就是說,原本應該加密、並驗證對方憑證的連線,會在沒有任何警告的情況下改用明文;gateway 遇到同樣情況會直接拒絕連線,不受影響。Istio 在 ISTIO-SECURITY-2026-006 公告中具名致謝,GitHub 公告列我為回報者。評分 CVSS 6.8,修正隨 1.30.4 與 1.29.7 發佈。

✓ Published

DRA 容量會計的迭代量隨租戶可控的數字成長,可癱瘓整個叢集的排程

能在叢集裡建立請求的使用者,只要把裝置數量填得很大,就能讓排程器的計算量跟著暴增,拖垮整個叢集的排程。修正先在私下的安全分支裡完成,再以 #5869 公開合併,隨 v1.15.2 發佈。公告列我為發現者。

✓ Published

insomniacslk/dhcp 的遠端 DoS 與下游升級

這是一次從頭做到尾的修復:在 insomniacslk/dhcp 的 DHCP client 找到可遠端觸發的當機問題,修好根因,補上測試與額外防護,向 Go 的漏洞資料庫通報,再到使用這個函式庫的專案逐一送 PR 升級。

  1. Found · 遠端可觸發 DoS

    收到一個過短的封包時,DHCP client 算出來的資料長度會變成負數,程式直接當掉。同一個網段上的任何人送一個畸形封包,就能讓使用預設收包方式的 client 停擺。

  2. Root fix · PR #583 merged

    封包短到放不下 UDP 標頭時,直接丟掉不處理。2026-07-20 合併。

  3. Regression + hardening in review

    #588 加上隨機輸入測試,拿一份獨立寫成的參考實作比對每個封包該收還是該丟;#589 在交出資料之前再檢查一次 UDP 長度;#591 不再接受分段的 IPv4 封包。#589 與 #591 還在審查中;#588 的測試照這兩支的規則比對,要等它們合併才會通過,目前是 draft。

  4. Reported · golang/vulndb #6237 triaged · high-priority

    向 Go 安全團隊正式通報。標籤上的 high-priority 是 Go 漏洞資料庫的處理優先順序,表示需要寫一份經過審核的報告,和漏洞的嚴重度(CVSS)無關。

  5. Advisory · GO-2026-6237 published · 2026-08-18

    Go 安全團隊審核後的報告已合併進漏洞資料庫(CL 816561,#6237 已關閉),2026-08-18 正式發佈為 GO-2026-6237,在 pkg.go.dev 查得到。仍不是 CVE:10/14 我請 Go 的 CNA 指派一個(golang/vulndb#6761),還在等回覆。公告也還沒列出回報者,請求補上具名的 golang/vulndb#6251 同樣開著。

  6. Downstream propagation · 11 merged

    到使用這個函式庫的專案送 PR,把相依升級到含 #583 修正的版本,11 支都已合併。

Selected upstream work

代表貢獻

依問題類型挑出幾支有代表性的合併。上面三組工作與安全修復提過的不再重複;全部 460 筆在 Ledger,那裡也看得到各基金會的分布。

規格與計費規則

KEP-2941:DRA firstAvailable 請求的配額計費規則

一個 DRA 請求可以列出好幾個備選裝置,由 scheduler 挑一個;但 Kueue 必須在 scheduler 挑之前就先扣配額。設計在 Alpha 階段要求每個備選指向同一種資源、數量也相同,這樣不管 scheduler 選哪個,扣一次就對了;數量不同的請求先拒絕,配置後再調整保留的配額,列為 Beta 的條件。實作在 #14130,也已合併。

✓ Merged

Remote-Write 2.0 規格:只帶 exemplar 的 TimeSeries

Remote-Write 2.0 規格說每筆時間序列至少要帶一個 sample 或 histogram,但 Prometheus 自己就會送出只帶 exemplar 的時間序列,等於規格說它自己的流量不合法。這支 PR 只改規格文字與 proto 註解,讓這種形狀合法,格式本身不動。bwplotka 起初擔心這會讓以 OpenTelemetry 為基礎的系統更難相容,要求修改;我說明 Prometheus 現在就會送出這種資料、並拿掉一條額外的建議之後才合併。Prometheus 原始碼裡同一段註解由 #19530 跟上,也已合併。

✓ Merged

並行與生命週期

ESP32 的 dma_stop() 在 GDMA 仍在寫入時就返回

結果是音訊(I2S)停止時,會把 DMA 還在寫的記憶體區塊交回去;每丟棄一次資料就漏掉一塊,漏光之後寫入音訊的呼叫就永遠卡住。修正讓停止時先重設 DMA 通道,確定硬體停下來才返回,並在 ESP32-P4 實機上測過。

✓ Merged

StatefulSet 穩態更新不得反覆排入 LeaderWorkerSet reconcile

原本的判斷式忘了 && 比 || 先算,整個條件只剩下檢查目前的版本號是不是空的。改成兩個版本號都存在、而且不同時,才算是在滾動更新。0.19 與 0.18 兩個發行分支也已帶回。

✓ Merged

正在被逐出的 slice 不得當 chain 的 active slice

否則系統會把一塊正在釋放的容量當成還能用,一次放行太多 pod。

✓ Merged

跨 driver 與 API 穩定

共享計數器快取綁定 driver 與 pool

以前兩個 driver 用了同名的計數器時,快取會把它們當成同一個,裝置因此被錯誤配置。

✓ Merged

多 driver ResourceClaim 的 result 守衛

一個請求可能同時由好幾個 driver 處理,這支修正讓 TPU driver 只處理屬於自己的那部分結果;官方範例 driver 本來就有這道檢查,這家漏掉了。

✓ Merged

workload-slice 相容路徑套用 priority-class 變更

相容路徑提早返回,剛好跳過唯一會套用新優先權的地方,所以改了 priority class 也不會生效;現在這條路徑也會套用。0.18 分支另外以 #13872 帶回。

✓ Merged

平台能力與安全預設

FOCOM 的 Porch client 沒有驗證 API server 憑證

設定值只要不等於字串 "true" 就會關掉憑證驗證,專案附的兩份部署設定又都寫成 "false",所以 operator 的存取權杖一直在沒有確認對方身分的連線上傳送。修正改成預設就驗證,要關掉得明確設定另一個名稱的選項。

✓ Merged

Argo Workflows 的 DRA resource claims

讓 Argo 的工作流程可以直接宣告要用哪些 DRA 裝置,設定會一路帶到實際執行的 pod;以前只能自己手寫 pod 規格的補丁。這是我先提案(#16576)再實作的。

✓ Merged

Under review

進行中重點

只挑一部分仍在上游審查中的列在這裡,合併後移入 Ledger。全部在飛的 PR 在 Ledger 的進行中清單,最新狀態以 GitHub 為準。

kubernetes-sigs/kueue

  • #13904LeaderWorkerSet 的更新路徑只解析一次 WorkloadPriorityClass縮小範圍後等 sohankunkerkar 審

kubernetes/kubernetes

  • #142355ResourceSlice 的分數容量以值比對、不比字串,也修掉 semx 回報的 #142489pohly 要求 hold 到 v1.39 再合併
  • #142322LimitRanger 的 limit 對 request 比例在任何 scale 都比得對semx 驗過兩端守衛
  • #141327kubelet 的 CPU 換算在 int64 邊界不再 wrap等 tallclair 終審
  • #141328scheduler NodeInfo 的加總飽和而不 wrap已 lgtm,等 approve

kubernetes/website

  • #57699Limit Ranges 文件補上更新時不再重新檢查的範圍等審

open-telemetry/opentelemetry-cpp

  • #4502Elasticsearch async export 的結果只回報一次,修自報的 #4338om7057 審查中
  • #4337Elasticsearch async ForceFlush 的 deadline 與完成計數draft

zephyrproject-rtos/zephyr

  • #120492esp32 legacy DMA 拒收超過 descriptor 容量的區塊sylvioalves、wmrsouza approve
  • #120491nrfx 配不到 RX buffer 時歸還 TX blocknordic-piks approve

上游狀態最後核對: