後端工坊 2026 年 7 月 15 日

2026-07-15 — C++26 靜態反射進入 GCC 16,BPF 高峰會探討直送封包與核心漏洞護盾

primary=https://isocpp.org/blog/2026/07/cpp26-enter-static-reflection-keith-stockdale primary=https://isocpp.org/files/papers/P2996R13.html primary=https://lwn.net/Articles/1081696/ primary=https://lwn.net/Articles/1081546/

C++26 靜態反射上路:從 ^^ 運算子到編譯期成員遍歷

isocpp.org Blog · 2026-07-13

GCC 16.1 已在主線編譯器中實作 C++26 靜態反射(static reflection)的核心語言與函式庫功能,讓開發者能在編譯期以 ^^ 運算子取得型別、列舉與成員的中繼資訊,再透過拼接(splice)語法把資訊重新生成為程式碼。這項能力源自 WG21 標準委員會通過的提案 P2996R13《Reflection for C++26》,作者群包括 Wyatt Childers、Peter Dimov、Dan Katz、Barry Revzin、Andrew Sutton、Faisal Vali 與 Daveed Vandevoorde。開發者 Keith Stockdale 在部落格記錄了他初次拿這項特性解決實務問題時,如何在標準文字與 Revzin 個人部落格之間來回查找的過程。

背景

C++ 長期缺乏原生的編譯期內省(introspection)能力,開發者若想枚舉一個結構的成員或把列舉值轉成字串,只能依賴巨集、程式碼產生器或第三方函式庫模擬反射。P2996 把「反射一個實體」變成一等語言操作:任何命名空間、型別或 id-expression 都能用 ^^ 取得對應的 std::meta::info,這是一個刻意設計成不透明的單一型別,用來避免把反射的內部表示綁死在型別系統上,留給未來語言演進空間。

核心改動與機制

拼接器(splicer)負責把 std::meta::info 重新變回具體語法:[: r :] 用於運算式、typename[: r :] 用於型別、template[: r :] 用於樣板。搭配 <meta> 標頭提供的一系列查詢函式,就能在編譯期走訪程式結構本身。

  • nonstatic_data_members_of() — 取得型別的非靜態資料成員清單
  • enumerators_of() — 取得列舉型別的所有列舉值
  • identifier_of() — 以 string_view 回傳實體名稱
  • members_of() — 取得所有成員
  • define_aggregate() — 在編譯期合成新的 struct/union 型別

下面是一個典型用法:把任意列舉型別的值轉成對應的識別字字串,不需要為每個列舉手寫 switch-case。

template<typename E>
constexpr std::string enum_to_string(E value) {
  for (auto e : enumerators_of(^^E)) {
    if (value == [:e:])
      return std::string(identifier_of(e));
  }
  return "<unnamed>";
}

影響範圍

GCC 16 目前提供的是部分實作,核心語言部分涵蓋反射運算子、拼接器、template for 展開陳述式(來自 P1306)以及 P3394 的標註(annotation)機制,需要以 -std=c++26 -freflection -fexpansion-statements 編譯。委員會另在 P3687《Final Adjustments to C++26 Reflection》中決定,把「拼接樣板引數」的支援延後到 C++29,因為對應的措辭與實作都還不成熟。對序列化、ORM 映射、日誌框架這類長期仰賴巨集或外部程式碼產生器的場景而言,這代表未來可以把型別中繼資訊查詢直接寫進標準 C++ 裡,減少對外部工具鏈的依賴。

原始來源:isocpp.org BlogWG21 P2996R13


讓 BPF 直接送封包:Tetragon 團隊提案繞過使用者空間代理

LWN.net · 2026-07-14

在 2026 年 Linux Storage、Filesystem、Memory-Management 與 BPF 高峰會(LSF/MM/BPF Summit)的 BPF 議程中,Cilium Tetragon 專案的 Mahé Tardy 提出讓 BPF 程式直接透過網路傳送資料的構想,藉此移除使用者空間代理(agent)這個可被攻擊者鎖定的單點故障。LWN.net 的報導記錄了這場討論的技術細節與核心開發者的回應。

背景

Tetragon 目前肩負兩項工作:執行安全政策,以及收集統計與可觀測性資訊。後者的現行路徑存在不必要的複製:BPF 程式把事件記錄寫入 ring buffer,再由 Tetragon 的使用者空間元件讀出,最後寫入檔案、管線或網路 socket,轉送到叢集之外的集中式監控服務。這條路徑的問題在於,一旦攻擊者能夠殺掉 Tetragon 的使用者空間代理,系統就再也無法正確回報當下的攻擊情形。

核心機制

Tardy 在探索替代方案時意識到,如果 BPF 程式被允許呼叫 vmsplice(),這個困境就能被繞過——使用者空間代理可以先把一個檔案描述子交給 BPF 程式,之後由 BPF 呼叫 vmsplice() 直接轉送資訊,不需要代理持續存活在關鍵路徑上。討論中也提到了讓 BPF 防火牆呼叫新 kfunc 送出 TCP RST 封包的可能性。BPF 子系統維護者 Alexei Starovoitov 則指出,核心裡已有一項使用 netconsole 把核心 log 訊息透過 TCP 傳送出去的既有工作。

  • 讓 BPF 程式呼叫 vmsplice(),取代目前的 ring buffer 轉送流程
  • 新增 kfunc,讓 BPF 防火牆程式能主動送出 TCP RST
  • 沿用 netconsole 的 TCP 傳輸機制,讓 BPF 程式的輸出直接印到主控台並轉送

影響範圍

Tardy 建議先從 netconsole 既有的 UDP 訊息機制做原型驗證,再決定是否投入 TCP 路徑的完整實作。這仍是設計階段的討論,尚未有對應的核心修補程式送出,但若成真,會直接影響仰賴使用者空間代理做集中回報的可觀測性與安全強制工具(不只是 Tetragon),减少代理存活與否對回報可靠性的影響。

原始來源:LWN.net:Sending packets directly from BPFCilium Tetragon


用 BPF 為執行中核心「加裝護盾」:Cisco 如何應對多分支核心的漏洞回應

LWN.net · 2026-07-13

在同一場 LSF/MM/BPF 高峰會上,Cisco 的 John Fastabend——BPF 資深貢獻者、Cilium 維護者,也是 Tetragon 專案的創始人——分享了他的團隊如何用 BPF 程式充當「護盾(shield)」,在核心漏洞尚未正式修補前,於執行中的核心即時攔阻利用手法。LWN.net 的報導詳述了這項技術如何縮短商用網路裝置回應核心漏洞的時間。

背景

Cisco 同時維護多條產品線,每條產品線各自跑著不同的穩定核心版本。用傳統的核心 live-patch 技術理論上可行,但代價是要為每一個分支各自撰寫、驗證並部署一份 patch,這需要投入大量工程人力,尤其是在漏洞剛公開、時間壓力最大的時候。

核心機制

Fastabend 團隊的做法是把攔阻邏輯寫成 BPF 程式,掛載在既有的 hook 點上,攔截並阻斷已知的利用路徑。BPF 程式的可攜性是這個方案的關鍵:同一支「護盾」程式通常能不經修改就跑在公司內部支援的各個核心版本上,不必像傳統 live-patch 那樣針對每個核心版本個別重新編譯與驗證,大幅壓低了跨分支同步修補的工程成本。

限制與影響範圍

這個方法能大幅縮短回應核心漏洞所需的時間,但 Fastabend 也坦言其效果目前受限於核心現有的 hook 點覆蓋範圍——只有在攻擊路徑經過的位置剛好有可掛載的 BPF hook 時,護盾才派得上用場,若核心裡缺乏對應的 hook,這套機制就無法介入。這也意味著要讓這個方案發揮更大效果,需要核心社群持續在更多子系統中加入新的 BPF hook 點,而非僅靠 Cisco 單方面的 BPF 程式開發。

原始來源:LWN.net:Shielding running kernels against exploits with BPF


End of article
0
Would love your thoughts, please comment.x
()
x