當最新 Linux 核心中 eBPF 的 pt_regs 讀取回傳亂碼時,怪 Fred (★ 100 分)
文章指出,從 Linux kernel 6.9 開始,x86_64 平台內核預設啟用一項名為 FRED(Flexible Return and Event Delivery system)的新功能,藉由引入 ERETU 及 ERETS 指令,以最佳化 CPU 權限等級切換。該功能在每個任務的內核堆疊區域底部額外新增 16 個位元組的填充,改變了 pt_regs 結構在堆疊中的排放位置。
作者在升級至 Linux kernel 6.11 後,於 Ubuntu 24.04 環境中發現原本正常運作的 eBPF 工具 xcapture-next 在讀取其他執行緒之 task_struct 內堆疊與 pt_regs 資料時,錯誤地將系統呼叫編號固定讀取為 getsockname(編號 51)。經過詳細排查,確定並非記憶體讀取失誤,而是由於新增填充導致原始位址計算偏差所致。
為因應此變動,作者展示其利用 bpf_core_type_exists 輔助函式動態檢查 FRED 結構是否存在,進而調整 raw eBPF 讀取邏輯以正確查找 pt_regs。該問題影響 Intel 及 AMD 平台,且僅透過核引數 fred=off 無法移除新增填充,文章提供詳細程式碼片段與調試脈絡,期望能幫助未來 eBPF 開發者節省大量除錯時間。
👥 11 則討論、評論 💬
https://news.ycombinator.com/item?id=43214576