Open Source · Audits
系統性正確性稽核
從一個缺陷抽象出審查不變量,跨專案追蹤同一失效模式。四條稽核線:跨專案資源會計變體、跨廠商 DRA driver、OCUDU NTN SIB19 路徑、Kueue 配額會計;每項附 issue、patch 與回歸測試。代表工作在 Overview、完整帳本在 Ledger。
Variant Analysis
從單點修正到跨專案缺陷模式追蹤
12 個缺陷變體 · 6 個獨立維護的上游專案 · 11 項修正已合併
從第一個資源會計錯誤出發,我將根因抽象為一組可重用的審查不變量:資源需求與配額計算在加總、乘法、數值轉換、共享配置與生命週期變更時,必須保持數值可表示、狀態一致,且不能因溢位、截斷、漏算或重複計數而失真。
接著,我以這組不變量系統性檢查其他排程器與 Dynamic Resource Allocation (DRA) 實作。其中「已承諾的配置效果不得因庫存更新而消失」這一條,另整理成 preprint 《No Capacity Resurrection》(SSRN),附 DRACheck 的可重現實驗,見 Publications。
十二項問題都由我發現,其中十一項開了 issue 回報(kueue 的型別邊界是 follow-up,直接送了修正)。十一項的修正已合併:十項由我提交、經上游維護者審查後合併,每一支都附帶回歸測試;KAI-Scheduler 的哨兵那一項由 eladb 修掉,屬社群修復。剩下一項雖已確認根因並備妥修正,因該 scaler 即將 deprecate 而由維護者以 wontfix 結案。
-
kubernetes/kubernetes int64 溢位 merged
配額會計把一個實際上無法滿足的 device 判成可配置
roundUpRange的min+step*n對大 capacity 請求 int64 溢位成負 · 回報 #140441 → 修復 #140442 -
kubernetes/kubernetes 型別邊界 merged
構造過的 step 值通過守衛後直接除零,打掛 allocator
守衛用精確的
Quantity.Sign()、算術卻用超出 int64 就截斷的Quantity.Value(),兩者對同一個值判斷不一致 · 回報 #140472 → 修復 #140666 -
kai-scheduler/KAI-Scheduler int64 溢位 merged
低估佇列需求而擋掉本應成立的 reclaim,受害的是同佇列的正常工作負載
-
kai-scheduler/KAI-Scheduler 哨兵 merged
一個 unlimited 的子佇列把兄弟的配額總和拉低,父佇列真的被超額時反而不警告
父子佇列配額檢查把子佇列 quota 原樣相加、不把
-1當無上限(父 10、子 -1 與 5 算出 4) · 回報 #1881 → 由 eladb 以 #2167 修(-1-aware 的加總與比較,2026-09-16 合併;社群修復,非本人提交) -
volcano-sh/volcano int64 溢位 merged
使用者可控的 device count 能繞過 capacity plugin 的配額
DRA 配額會計直接在原生
int64上加總,未設任何上界 · 回報 #5620 → 修復 #5621;殘餘的addDRAResource累加路徑由 #5625 補上(2026-09-16 合併、backport 至 release-1.15) -
volcano-sh/volcano 無上界迴圈 merged
一個帶超大 device count 的 Pod 就能讓 scheduler 的 goroutine 永遠不回來、記憶體無界成長(scheduling DoS)
addDRAResource用「迭代 count-1 次逐次相加」算容量總和,count 直接來自 ResourceClaim、apiserver 只擋非正值 · 回報 #5627 → 修復以Quantity.MulO(1) 相乘(master commitc7fb3fe7,經私有 advisory fork)與 #5869 的 1.15 backport;GHSA-j38h-7pfq-cxmw,本人具名 finder -
kubernetes-sigs/kueue int64 溢位 merged
超額 Workload 被 admit,並汙染 ClusterQueue 的已用配額
-
kubernetes-sigs/kueue 乘法溢位 merged
同一條路徑的第二處,counter 扣款仍可溢位
counter-charge 的乘法未設守衛,是 #12897 修完後補上的第二輪 · 回報 #12908 → 修復 #12909
-
kubernetes-sigs/kueue 型別邊界 merged
driver 自行發布的 counter 值不受 apiserver 驗證,負值或超界量直接算錯配額
maxValue.Value()在乘法之前就把超出 int64 的量截成垃圾(1e19變 0、2^63變負),飽和乘法救不回來;且該保護只在count > 1時啟用 · 修復 #12945(follow-up,無獨立 issue) -
kubernetes-sigs/kueue 哨兵碰撞 merged
用量飽和到
MaxInt64就與「無上限」分不開,之後的 workload 加進來不計、離開時照減,配額帳面往下漂直到重啟Amount以math.MaxInt64當 unlimited 的哨兵、只在 quota 邊界守著;usage 邊界的Mul/AddInt64飽和後正好落在哨兵上,clamp 擋得了碰撞擋不了移除時的漂移 · 回報 #14105 → 修復 #15026(改為 int64 放不下就轉big.Int的精確整數,2026-09-16 合併) -
cncf-tags/container-device-interface slice 邊界 merged
單字元的 vendor 或 class 名稱就足以讓解析 panic
validateVendorOrClassName切出name[1:0],低界大於高界;兄弟函式本來就有這道守衛 · 回報 #320 → 修復 #321 -
kedacore/keda off-by-one wontfix
總 lag 落在分區邊界時封頂失效,多要一個 replica
封頂用整數 floor 除法比較、HPA 卻以
ceil算 replica,兩者取整在邊界分歧而漏夾 · 回報 #7930;已備妥>=修正與回歸測試,維護者因該 liiklus scaler 即將 deprecate(#7929)而以 wontfix 結案(非否定 bug)
同一子系統的縱深:Kubernetes DRA structured allocator
跨專案追蹤缺陷變體之外,我也在 Kubernetes 核心 DRA allocator 中沿著資源會計不變量持續向下檢查。五項已合併修正涵蓋數值表示與溢位(#140666、#140442)、跨 driver 的 counter-cache 身分碰撞(#140435)、候選拒絕與回溯時的狀態洩漏(#140431),以及持久化共享裝置的 counter 重複計算(#140437)。
五支 PR 均已合併至 master、帶有 release-note 標籤並列入 v1.37 milestone;每支均關閉一個由我回報的 issue,並附有針對原始失效路徑的回歸測試。這些改動落在 staging/src/k8s.io/dynamic-resource-allocation,由 Kubernetes 的 publishing bot 同步到唯讀的 k8s.io/dynamic-resource-allocation(14 個 commit)與 k8s.io/apimachinery(8 個,Quantity 那條線)出貨。那個模組正是下一節各廠商 driver 所 import 的同一份程式碼,所以核心的配置正確性與各家 driver 的 result 守衛是同一條相依邊的兩端。那些鏡像 repo 關閉 issue 與 PR、只接受機器人同步,不另計為合併,Merged 只算 kubernetes/kubernetes 這一邊。
上游制度化:SIG API Machinery 的 Quantity int64 burndown
這條 int64 溢位家族後來被上游收攏成正式工作項。SIG API Machinery 維護者 jpbetz 在 #141166 開了官方 burndown、系統性追蹤整個 resource.Quantity int64 accessor 溢位 class(乘法 wrap、負值捨入方向、String() 掉後綴、指數截 32-bit 等),並具名 CC 我。我供稿其第一項:#141170 的 baseline accessor 測試矩陣:記錄 Value/MilliValue/ScaledValue 等每個 accessor 今日的實際回傳、對錯誤值標 TODO,讓後續每項修正都對「已知基準」做 diff 而非憑記憶(2026-08-26 合併)。這條線在 2026-09-10 收束到 API 層:#141305 讓 Value/MilliValue/ScaledValue 從溢位靜默 wrap 改為依正負號飽和,並新增 AsScaledInt64/AsMilliInt64 讓呼叫端拿得到「裝不下」這個事實,而不是拿到一個壞值(+623/-187、10 檔,kind/api-change、sig/api-machinery、release-note)。同日 #141349 修掉同一條線上的驗證側:ValidateResourceQuantityValue 以 MilliValue()%1000 == 0 判斷整數,而該投影會飽和、MaxInt64 % 1000 是 807,於是 10P、1E 這類整數被以「must be an integer」拒絕;改用 Quantity.AsScale(0) 的第二個回傳值作答,並刻意只處理會飽和的那一段,以 8,804 種寫法差分驗證沒有任何值從接受變成拒絕。隔日再合併三支:#142013 把 Quantity.Cmp 本身界定住(scale 差以 int32 相減會繞成負數、pow10Int64 回 0 然後除以它);#141348 讓 LimitRanger 的 min/max/比例改走 Cmp,review 時第一版的本地 helper 被指出繞過的慢路徑就是 Cmp,所以先修 Cmp 再直接呼叫;#141618 讓 PVC 指名 PV 的容量檢查跟自動配對那條路一樣用 Cmp(修自報的 #141617)。這條線的兩個「用錯 accessor 的呼叫端」與「accessor 本身」到此都已合併。
不變量的最新延伸(回報中)
同一組資源會計不變量持續在新的專案表面發掘變體。近期兩則回報把它帶出 Kubernetes 排程器、落到容器執行期的資源設定層:opencontainers/cgroups #73(systemd 的 addCPUQuota 把大 CPU quota 換算成 cgroup 週期值時 int64 溢位、寫出一個極小的配額而靜默限流)與 kubernetes #141323(DRA structured allocator 在 per-claim 上限檢查時,用原生 int 加總 device count 而溢位)。兩者均由我回報。kubernetes #141323 的修正 #141307 已合併進 master(+148/-75),但 pohly 為了追 backport 到 1.34-1.37 把該 issue 重新開啟,四支 cherry-pick(1.34 到 1.37)於 9/12 由 patch release team 陸續放行、當日全部合併;cgroups #73 在該 repo 內仍無修正,Kubernetes 側的 #141327 標著 work-in-progress。兩者都不計入上列 9 個變體:列此是因為它們是同一不變量往新專案的延伸,而非另一種缺陷。至於 Merged 與 Found & Fixed,#141307 與四支 backport 本來就各自計在帳本裡;#141323 在四支 cherry-pick 到齊、於 2026-09-12 以 completed 關閉之後也已列入 Found & Fixed。cgroups #73 在該 repo 內仍無修正,兩邊都不計。
Kubernetes DRA
跨廠商 DRA driver 正確性稽核
9 個 driver · 8 個組織 · 其中 5 家同一個「多-driver claim」缺陷(★)
Dynamic Resource Allocation(DRA,Kubernetes 1.34 GA)讓每個廠商用自己的 driver 把硬體交給排程器。我沿用缺陷變體分析法橫向稽核多家 driver,發現一個反覆出現的共通假設:「claim.Status.Allocation.Devices.Results 裡的每一筆都是我這個 driver 的」。但一個 ResourceClaim 可由多個 driver 一起滿足,於是這個假設在五家不同廠商的 driver 上各自爆開(★ 標記)。已 merged 的修正見 Ledger 合併清單。
-
dra-driver-google-tpu · Google ★ multi-drivermerged
prepareDevices把整包Results都套 TPU 專屬檢查(full-chip 數、allocatable、container edits)→ 同一 claim 又要別 driver 的裝置時,完整 TPU 配置反被拒(錯誤訊息還文不對題)。改為只算本 driver 擁有的 result · 自報 #26 + 自修 #25 -
power-dra-driver · IBM ★ multi-drivermerged
prepareDevices逐一在本 driver 的allocatable查每個 result,別 driver 的裝置不在集合裡 → 整包回not allocatable、混用兩 driver 的 pod 起不來(config 路徑GetOpaqueDeviceConfigs早就跳過別 driver,result loop 漏了)。改為result.Driver != DriverName就跳過 · 自報 #322 + 自修 #323。同一次稽核還提了更深一層的 #324:修好 driver 之後,result 仍只比對 driver 與裝置名、沒有比對Pool,同一 driver 但屬於別的 pool 的 result 依然能被套到本節點的加速器上。維護者 prb112 以「這顆晶片只有單一 co-processor、用途是測試」為由結案,沒有對應修正 -
dra-driver-spyre · IBM(Spyre AI) ★ multi-driver + nil panic部分已修 · #65 merged
#59
prepareDevices拿別 driver 的 result 去對 Spyre 裝置 map 解析、多-driver claim 整包失敗;#58Unprepare在 CDI spec 檔已消失時對nil取ContainerEdits→ nil 指標 panic · #59 已修:該 repo 現階段只收 collaborator 的 PR(維護者 sunya-ch 在串上言明),因此由他依此報告自行實作 #65(foreign driver conflict filter,+352/-15,trent-s approved),2026-08-28 合併並關閉。本人回報、維護者實作;同列的 #58 仍開 -
dra-driver-sriov · Network Plumbing WG ★ multi-drivermerged
#136 status update 撞 conflict 重試時,把整個
status.devices換成第一次嘗試前的快照 → 別 driver 在衝突視窗內寫的條目被蓋掉(同家族,這次落在 status-retry 路徑);做修正時又找出 #138:refetch 只按 namespace 與 name 取回、不核對 UID,claim 被刪掉重建時會把狀態寫到同名但不是同一個的物件上 · 自修 #137 一併修掉兩者,8 月 4 日送出、審查一個多月從 +243/-4 長到 +799/-71,wizhaoredhat 與 SchSeba approve 後於 2026-09-14 合併,#136 與 #138 同日關閉 · 同 repo 的 #140 與 #143 由 #168 一併修(status 重試改成在最新 claim 上套 mutation、NRI runner 的關閉競態與背壓,+2224/-594,2026-09-17 送出、審查中);同日 #169 修DeleteClaim對多 claim 的 Pod 只清第一個、其餘 VF 從未 unprepare 的問題 -
dra-driver-nvidia-gpu · NVIDIA ★ multi-driver部分已修 · #1328 merged
partial DynamicMIG rollback 把 claim 裡每一筆 result 的名字都交給 MIG 拆除,同一個函式的 VFIO 那一半與另外三個迴圈都檢查
r.Driver、只有這裡漏了;別家 driver 的 result 之所以會在我們的 checkpoint 裡,是Prepare()把整份 claim status 存了進去,而 kubelet 會把同一個 claim 交給結果裡列到的每一個 driver。今天的 main 上名字解析出的 tuple 少了ParentPCIBusID、查找先失敗,所以拆不到東西,但那是 #1452 的回歸,修好之後這條路就通了 · 自報 #1327 + 自修 #1328(rollback 守衛,varunrsekar 9/22 合併,手工回移 release-0.5 的 #1477 同日合併);checkpoint 那一半 #1371 審查中,只寫自己 serve 的 result、並讓帳目對不上的 claim 不拆裝置;#1327 留到兩半都落地 -
dra-driver-cpu · Kubernetes SIG 設定/生命週期7 merged
上游參考實作:已合併 #215/#257/#259/#272/#273(設定鍵大小寫折疊繞過排除、kubelet-root 可設定且 fail-closed、SIGTERM graceful shutdown 等,見 Ledger);kubelet-root 的收尾 #274(chart 從單一值推出接線,8/10 合併)與 #282(拒絕 kubelet 只在參數裡改寫的路徑、接線進 CI 與 relocated-root e2e lane,ffromani 兩輪 15 則意見後 9/17 合併)也已落地,自報的 #231 同日關閉
-
k8s-gpu-dra-driver · AMD 非決定性/衛生2 merged
已合併 #74/#76:ResourceSlice 裝置依 Go map 序發佈、每次重啟順序不同(影響 scheduler first-fit)→ 按名稱排序;
.gitignore未錨定連cmd/原始碼一起忽略 -
composite-dra-driver · Red Hat shadow/pairing 生命週期進行中
shadow claim 身分/生命週期一叢(皆自報、修正 PR 審查中):名字漏帶 parent claim UID 致同名重建認領到舊 shadow(#65 → #66)、
unprepareClaim在底層 unprepare 成功前就丟 recovery state 致資源洩漏被 retry 掩蓋(#64 → #67)、prepareClaim忽略啟動時還原的狀態、改從 mutable device store 重建(#68)、auto-pairing 讓兩個 composite 裝置共用同一實體裝置(#69)、create/update-status 部分失敗後留下無 allocation 的 shadow 卡住(#70);另補 1.36DRAResourceClaimGranularStatusAuthorization所需的resourceclaims/bindingRBAC(否則 shadow status 更新在 1.36 被拒;#71、1.35 惰性、forward-compat) -
HAMi-DRA · Project-HAMi CEL 注入/webhook社群修復 · #91 merged
#73 mutating webhook 的
addAnnotationSelectors用fmt.Sprintf把原始 annotation 值直接拼進 CEL 字串字面值,沒 quote 也沒 trim。值裡帶引號或反斜線就長出["GPU-1""],API server 驗 CEL 時擋下、webhook Create 失敗、回滾前面容器已建的 claim、pod 被拒,還只回一個 CEL parse 錯誤看不出是 annotation 的問題;沒 trim 的安靜版是GPU-1, GPU-2變成含空格的" GPU-2"、比不到任何裝置 · moezdil 以 #91 加上引號與 trim 修掉,非本人提交
O-RAN / NTN
OCUDU NTN SIB19 路徑正確性稽核
12 個缺陷 · 分屬 5 種類別 · 同一 NTN SIB19 更新路徑
OCUDU(Open Centralized Unit Distributed Unit)是 srsRAN Project 的後繼專案,承襲其 5G CU/DU 程式碼、系統架構與開發脈絡。程式碼由 GitHub 移轉至 GitLab,主要授權亦由 srsRAN Project 的 AGPLv3 改為較寬鬆的 BSD-3-Clause-Open-MPI。OCUDU 的初始建置計畫於 2025 年公布,由美國 FutureG Office 透過 National Spectrum Consortium 提供經費,交由 DeepSig 與 Software Radio Systems(SRS)共同建置初始軟體。
Linux Foundation 於 2026 年 3 月 1 日在 MWC Barcelona 宣布成立 OCUDU Ecosystem Foundation,將技術專案置於中立、跨組織的開源治理架構之下。創始成員包括 AMD、AT&T、DeepSig、Ericsson、Nokia、NVIDIA、SoftBank、SRS 與 Verizon。SRS 是初始 CU/DU 程式碼的重要建置者及核心技術貢獻者之一。
OCUDU 並非在 2026 年 7 月才開始支援 NTN(Non-Terrestrial Network,非地面網路)。其前身 srsRAN Project 在 24.4 版已加入 GEO NTN 與 SIB19 支援,OCUDU 的初始 26.04 版本亦保留 GEO NTN 能力。2026 年 7 月期間 dev 分支密集合併 SIB19 廣播、TN/NTN 鄰區資訊、衛星切換、饋電鏈路 timing advance 與動態 SIB19 更新等擴充,是 NTN 實作快速演進與協定正確性加固的階段。
我沿用前述缺陷變體分析方法,對這條剛落地的 NTN SIB19 更新路徑(du_high、du_manager、MAC 排程與 ntn 數學)逐段稽核,辨識出 12 個缺陷、分屬五類:記憶體生命週期、環狀與規範時間邊界、數值退化與界限、錯誤處理與交易性、狀態失同步。
這 12 個缺陷的處置在 8 月中有實質進展:!1153 經 SRS review 縮為單一 use-after-free 修正、合併至 dev,關閉 #643(見下方縱深一);其原一併提出修的另 6 項(#652/#653/#654/#655/#656/#657)在 review 中被移出範圍、修正未落地、issue 仍開。!1242 已合併,關閉 #695 的 SI-window 計算。!1162(#658 全 0 廣播)仍審查中、需 rebase。!1096 的 SIB19 epoch numerology 部分已合併、但未關聯本稽核任一 issue;其原含的 #649 修正因與 dev 重複而撤回、issue 仍開。#659 的 epoch off-by-one 修正(!1163 → !1241)皆未合併、issue 已由維護者關閉。#660 亦由維護者關閉。#643、#695 為自報並修復,!1153/!1242/!1096 已合併 PR。
-
du_high · SIB19 use-after-free 已修 · !1153 merged
SIB19 更新把非持有
span與區域 request 的 reference 交給延後 coroutine,呼叫端返回後即成 dangling後續 DU update 與 MAC reconfiguration 讀已釋放記憶體 · 回報 #643 → 修正 !1153 已合併、#643 以 completed 關閉(詳見下方縱深一)
-
MAC · SI-message 環狀歧義 回報中
slot_point在正好半個 hyperframe 處排序未定義,佇列中的 SIB19 更新可能早約 512 frames 套用si-Periodicity rf512 恰為 1024-frame hyperframe 之半、踩在比較邊界 · 回報 #649 → 原提 !1096,因與
dev的si_messages_collide_pred重複,作者撤回此部分;issue 仍開 -
ntn · config off-by-one 已關閉
epoch time 比 TS 38.331 定義的 SI-window end 晚一個 slot(15 kHz 為 1 ms)
epoch 是 serving-satellite ephemeris 與 Common TA 的時間參考,偏移使衛星位置參考失準 · 回報 #659 → 原提 !1163 因上游 !1216 移除依附的 epoch CLI 參數而撤回,於 current dev 重提為 !1241(去掉
+1);!1163、!1241 皆未合併,#659 已由維護者關閉、無 merged 修正 -
ntn · orbital 退化 NaN 已關閉
赤道或圓形軌道(合法幾何)令
acos分母歸零,NaN 灌進還原軌道要素、SIB19 與 ephemeris propagationeci_to_orbital的 0/0 →acos(NaN)=NaN · 回報 #660,維護者於 2026-08-05 關閉(無對應 MR) -
du_manager 窄化截斷 回報中
sib_idx從unsigned窄化為uint8_t無範圍檢查,>255 靜默截斷後才進 MAC回報 #656 → 併於 !1153 提出,惟該 MR 於 review 縮為單一 use-after-free 修正、此項未落地、issue 仍開
-
MAC · SI 組裝 界限失守 回報中
SI 緩衝的
tbs ≤ 2048界限只有 debug assert,release build 無守衛 → OOB read封裝把固定 2048-byte 緩衝以 grant
tbs長度的span交下層、無 runtime 檢查 · 回報 #652 → 併於 !1153 提出,惟該 MR 於 review 縮為單一 use-after-free 修正、此項未落地、issue 仍開 -
du_manager 背壓丟棄 回報中
主控迴圈佇列(bounded 128)滿時,NTN 參數更新無 log、無 retry、無 error 靜默丟棄
回報 #653 → 併於 !1153 提出,惟該 MR 於 review 縮為單一 use-after-free 修正、此項未落地、issue 仍開
-
du_manager 非交易 回報中
更新無交易邊界,中途失敗留半套狀態;多 cell 時已提交的 cell 跳過 F1AP CU 通知
assistance info 在 SIB19 reconfig 可能失敗前就寫進 live cell config · 回報 #654 → 併於 !1153 提出,惟該 MR 於 review 縮為單一 use-after-free 修正、此項未落地、issue 仍開
-
du_manager 忽略錯誤 回報中
忽略
update_ntn_assistance_info的false回傳,更新失敗的 cell 仍走完流程並可回報成功回報 #655 → 併於 !1153 提出,惟該 MR 於 review 縮為單一 use-after-free 修正、此項未落地、issue 仍開
-
MAC · SI-message 無 rollback 回報中
多 PDU 逐一 push,中途某次失敗即返回,已 push 的留在佇列不回滾 → 部分套用
回報 #657 → 併於 !1153 提出,惟該 MR 於 review 縮為單一 use-after-free 修正、此項未落地、issue 仍開
-
MAC · assembler 狀態失同步 已修 · !1162 merged
encoder 向量每次 reconfig 縮放、content cache 只增;特定 remove-then-re-add 後未變內容的 SI 被廣播成全 0
-
du · SI-window 規範時間邊界 部分已修 · !1242 merged
稀疏或過高的
si-WindowPosition通過現有 count 檢查,但 TS 38.331 的SFN mod T = floor(x/N)對它無解 → 該 SI 訊息永不排入;碰撞判定又混用單位、漏報真正的視窗重疊validate_cell_sib_config()缺每則訊息的 offset-within-period 上界((si-WindowPosition-1)*si-WindowLength < si-Periodicity*slots_per_frame),且 collision predicate 拿「SI window」單位的 position 差對「radio frame」單位的gcd取模、量綱不一致 · 回報 #695 → 修正 !1242 merged,只修了get_next_si_win_start()的視窗計算;validate_cell_sib_config()的 offset 上界與碰撞量綱沒有隨之落地,而維護者 ismael.gomez1 已於 2026-09-07 在 !1242 合併後關閉 #695
縱深一:非同步生命週期安全(#643 → !1153)
SIB19 更新路徑將指向區域 std::vector<byte_buffer> 的 non-owning span,連同對區域 request 的 reference,交給延後執行的 coroutine。原始 handler 返回後,request 與 span 的 backing storage 均已失效,使後續 DU update procedure 與 MAC reconfiguration 讀取已釋放的記憶體。
已合併的 !1153 將 SI message buffers 改為由 request 持有(span → std::vector<byte_buffer>),並以 value/move semantics 端到端傳遞至 coroutine 與 procedure。新增的端到端回歸測試經 ASan 驗證:修正前觸發錯誤、修正後通過;另以 mutation testing 分別還原 reference capture 與 non-owning span,確認測試能獨立捕捉兩條生命週期失效路徑。此 MR 由維護者 Piotr Gawłowicz approved、合併至 dev,關閉 #643。
縱深二:整條 NTN 更新程序的錯誤處理缺口
#653、#654、#655 與 #657 同屬一條 NTN parameter update 程序,問題是它端到端缺乏錯誤處理與交易性的四個面向:佇列滿時靜默丟棄、失敗留半套狀態且不 rollback、忽略失敗回傳報假成功、MAC 多 PDU 中途失敗不回滾。此四項未含於已合併的 !1153 最終範圍,仍為回報中、待後續 MR。
另記兩項
#642 epoch_time 設定契約:serving-cell 的 epoch_time 文件化為 SIB19 EpochTime 的覆寫值,但 build_sib19_info 從未讀取;因同一 epoch 亦用於 ephemeris propagation,宜整體處理。目前等待維護者決定完整實作 override 或移除欄位並保留 epoch_sfn_offset。
#633 CI 供應鏈(非 NTN 協定):CodeChecker CI builder 釘 6.26.1,其 bundled ldlogger 受 CVE-2025-40843 影響(6.26.2 已修);現行 CI 使用 analyze/parse、未觸及受影響的 CodeChecker log,屬預防性升版與供應鏈衛生。
Kueue · Resource transformation
Kueue 配額會計正確性稽核
7 個缺陷 · Kueue 配額會計與資源轉換驗證
Kueue 依 config 的 resourceTransformations/deviceClassMappings 換算資源、再連同 PodSet 請求計入配額。我以「設定要先驗證、charge 計算不得靜默失真、且結果可重現」為不變量,對 validateResourceTransformations/validateDeviceClassMappings/applyResourceTransformations/validatePodSet/ResourceValue 這條路徑逐段稽核,目前辨識出七個缺陷:負係數做減法、保留名未擋、撞名非決定性、Retain 保留乘積、spec.overhead 漏驗、正積 int64 截斷 wrap、extended-resource 替換連坐刪除。方法同我在 Kubernetes int64 溢位家族與 DRA 跨廠商稽核。
以下皆本人自報。五項已由本人的 PR 修好合併(#13986 一發三修、#13989、#14042)。另兩項:一項修正 PR 仍在審查(#13995),一項尚無修正。
-
config · transformation 數值/負值 已修 · #13986 merged
負係數的 transformation output 等於做減法,
totalRequestsFromPodSets事後FloorToZero把它抹平 → 配額被靜默抵銷、少算validateResourceTransformations只查策略與重複輸入、沒擋負 output · 回報 #13985 → 修正 #13986 merged(2026-08-09,一發三修) -
config · deviceClassMappings 保留名未擋 已修 · #13989 merged
pods是 Kueue 內部 Pod 計數保留名,workload webhook 有擋、operator config 卻沒擋 → 名為pods的 DeviceClass mapping 得以載入、DRA charge 混進 PodSet 計數、配額算錯validateDeviceClassMappings只查 label-key 語法/長度/唯一性、未比照 webhook 拒絕保留名 · 回報 #13988 → 修正 #13989 merged(2026-08-24,並 cherry-pick 至 release-0.18 #14758) -
config · transformation 非決定性 已修 · #13986 merged
transformation output 與 PodSet 直接請求的資源撞名時,保留或覆蓋由 Go map 迭代順序決定 → 同一份 config 每次配額可能不同、不可重現
applyResourceTransformations對 output 用累加、對保留/未轉換 input 用賦值、共寫同一個 map · 回報 #13990 → 修正 #13986 merged(一發三修) -
config · transformation 狀態污染 已修 · #13986 merged
Retain策略應保留「原請求量」,但multiplyBy先把inputQuantity就地改成乘積 → Retain 寫回的是乘積而非原量、配額被放大applyResourceTransformations在multiplyBy分支重新賦值inputQuantity,Retain 又用同一變數寫回output[inputName]· 回報 #13992 → 修正 #13986 merged(一發三修) -
quota · ResourceValue int64 截斷 已修 · #14042 merged
transformation 乘出的大正值經
ResourceValue的Value()(僅 CPU 走SafeMilliValue)→ 超 int64 靜默截斷、可 wrap 成負請求、再被FloorToZero抹平ResourceValue只守 CPU 路徑、其餘用q.Value()(big.Int超界未定義);SafeValue正是為此存在卻沒用上 · 回報 #13998 → 修正 #14042 merged(2026-08-10) -
webhook · validatePodSet 驗證漏網 審查中
spec.overhead是配額 charge 的一部分(totalRequestsFromPodSets未ExcludeOverhead),non-negative 驗證卻沒查它 → 負的 overhead 進得了配額計算validatePodSet只驗 init/containers 與 pod-levelspec.resources、漏了spec.overhead· 回報 #13991 → 修正 #13995(WIP)審查中 -
workload · extended-resource 連坐刪除 已修 · #14154 merged
extended resource 由 DeviceClass 背書時,workload builder 刪掉整個 resource key、只補回
ResolveExtendedResourceQuota從 container 重建的 charge → 同 key 上的其他貢獻(spec.overhead、transformation output)被一併刪除、無人補回、配額少算ResolveExtendedResourceQuota只走 container、但PodRequests會加 overhead、transformation 又在刪除前先跑 · 回報 #14004 → 修正 #14154 merged(只取回 charge 實際替換的部分,2026-09-22,並回移 0.19 與 0.18)
Audits in flight
進行中的系統性稽核
5 條稽核線 · 橫跨可觀測性、批次排程、嵌入式驅動、宣告式基礎設施與節點執行期
上方四區是已收斂的稽核;這裡是仍在飛的,多數為已回報、部分修正已合併或在上游審查中。
-
kubernetes · kubelet 靜態連結 build 模式/執行期語意 10 落點、3 個專案 · 4 已修
把 kubelet 改成靜態連結(
CGO_ENABLED=0)會換掉 Go 標準庫走的實作路徑:沒有 cgo 的os/user只讀/etc/passwd、不經 NSS,而-race本身就需要 cgo。不變量是「改變 build 模式不得改變執行期語意」,沿著它掃這個改動的落地面根因是 dims 的 #135870(2026-09-09 合併)。代表:
getKubeletMappings()遇UnknownUserError就回內建預設區間、getsubids從沒跑過,於是同一台機器上 kubelet 是不是用 cgo 編的會決定它挑到不同的 subordinate ID 區間(#141940,dims 隨 #135870 一併修掉);kubelet 進KUBE_STATIC_BINARIES後完全帶不了 race instrumentation,DRA 與 kind 的 race job 等於在測一個沒插樁的 kubelet(#141942,應 dims 要求拆成獨立 issue 後,由 dims 以同名的 test-infra#37840 修掉,自提的 #37842 讓路關閉)。另補上 kubeadm 對getent缺席的 preflight 警告(#141968 已合併),並讓getent不可用時退回os/user(#141971,rata 要求砍到只剩 fallback、自掛 hold 等 halaney 的 #141345 先落地);#141970 與 #141941 仍開。9/12 追到 OS 層:shadow-maint/shadow#1738,getsubids把「沒有區間」「帳號不存在」「檔案讀不到」印成同一句、同樣 exit 1,libsubid 有狀態 enum 但 CLI 看不到;共同維護者 alejandro-colomar 11 分鐘內回「Sounds reasonable」,隔日依他的要求把修正拆成兩支送出:#1740 讓 libsubid 複製 NSS module 回傳的陣列再交出去,沒有區間的使用者於是拿到零長度配置而非 NULL,alejandro-colomar 五十則逐行意見、hallyn approve 後於 2026-09-15 合併;#1739 讓getsubids能分流結束碼,設計在審查中從新增ranges2介面改成 libsubid 失敗時設 errno(ENOENT/EAGAIN/EIO),alejandro-colomar 9/16 進一步提議直接改既有 API,審查中。同日再私下回報 Kubernetes SRC:NSS backend 斷線時帳號查詢回「no such user」,kubelet 落回預設 ID 池而非管理員設定的範圍;getent在六種 nsswitch layout 下全部 exit 2、從不回報 backend 不可用,所以 master 自 #135870 起每一種 layout 都 fail open,見 Issues 頁 -
opentelemetry-cpp · curl HTTP client 併發/生命週期 14 回報 · 4 已修
一個 curl HTTP client 的 session 取消、重試、事件回呼與 easy-handle 資源釋放,在多執行緒下的一整組競態、死鎖、use-after-free 與洩漏
代表:
Abort對 easy handle 的 use-after-free(#4375 已修)、resetMultiHandle自我死鎖(#4389 已修)、FinishSession於 OnEvent handler 死鎖(#4402)、重試 deadline 每次呼叫重畫(#4403)、Setup 失敗洩漏 easy handle(#4397)· 完整清單見 GitHub -
kueue · DRA extended-resource/配額會計 配額正確性 承上 · 30+ 回報 · 15+ 已修
承上方 Kueue 配額會計稽核:DRA extended-resource 的對映、charge、workload overhead 與 transformation,在漏算、重複計、負值與 int64 溢位下的一整組配額正確性缺陷
代表:source-backed device class 零計費(#14249)、overhead 未核對配額(#14274)、pod-level request 未核對(#14255,Dasmat13 以 #16047 修)、DRA 負 request 抵銷他項(#14216,pujitha24 以 #14367 修)· 跨專案:同一「shared ResourceClaim 記帳」invariant 亦見 volcano #5847(ancestor queue 對共享 claim 雙向漏記)· 完整清單見 GitHub
-
zephyr · ESP32 GDMA/I2S driver 邊界/狀態機 14 回報 · 9 已修
ESP32 GDMA descriptor 生命週期與 I2S 狀態機轉移的邊界解參考、零長度區塊、停止 fall-through 與硬體狀態誤讀
代表:descriptor-exhaustion 對 list 尾端後一格解參考(#115502 已修)、
dma_esp32_stop()fall-through 把同方向停兩次(#115503 已修)、i2s TX start 失敗漏還 mem-slab block(#115504 已修)、deferred TX timer 停止後不取消(#115505 已修)、不支援方向 trigger NULL deref(#115719 已修)、零長度 block 變 DMA-owned(#115720 已修)、PM policy lock 共用一旗標(#115722,raffarost 以 #117706 修復)、stop 留著鎖存的中斷狀態使下一次 start 先送出上一筆的 callback(#115726 已修)、AXI channel 略過 abort 握手(#116336 已修)· 仍開的五則:#113310、#115499、#115717、#115801、#116337 · 完整清單見 GitHub -
crossplane · ControllerEngine 生命週期競態 3 缺陷 · 修正在飛
動態 controller 在 engine 換手時的啟停競態:失敗清理誤停接手的新 controller、已停止的 source 仍被註冊 event handler、watch 被加到已停止的 controller
回報 #7728/#7730,修正 PR #7727/#7729/#7731 於上游審查中 · 完整清單見 GitHub