LWN.net has published an examination — behind its subscriber paywall — of how vendor hooks became the surviving channel for out-of-tree divergence in the Android kernel, despite years of work to collapse OEM and chipset forks into a single shared image.

The core tension is simple. Android's Generic Kernel Image (GKI) programme promised to end the long-standing problem of every device shipping its own forked kernel: device makers would build on one certified, common kernel image, and the differences that remain would be expressed through sanctioned extension points rather than by patching kernel source directly. That promise has been partly kept. What the LWN piece documents is the mechanism through which a great deal of divergence persists anyway.

From forked source trees to hook symbols

For most of Android's history, vendors carried substantial out-of-tree modifications: scheduler tweaks, power-management changes, driver integrations and security patches maintained as private source diffs that had to be rebased against every new kernel release. GKI was designed to shrink that delta. Broad rollout began with Android 11; the hard mandate arrived at Android 12 with GKI 2.0, standardising on the 5.10 LTS kernel.

Today, the preferred form for a vendor change is no longer a direct kernel patch but a hook. In the Android Common Kernel tree, hooks are declared using the DECLARE_HOOK and DECLARE_RESTRICTED_HOOK macros, with the declarations living under include/trace/hooks/. These generate callable symbols in the android_vh_* (vendor hook) and android_rvh_* (restricted vendor hook) namespaces, which out-of-tree modules — typically the binary driver blobs that ship with a specific SoC or peripheral — can register callbacks against.

The asymmetry between the two classes matters. Ordinary vendor hooks are broadly callable. Restricted hooks, by contrast, are gated so that only first-party modules can attach to them, enforced through the GKI module signing allowlist — the abi_gki_aarch64 entries that determine which modules the shipped image will load. This is the quiet governance layer of the whole arrangement: the hook surface is not merely a technical API, it is a permissioned one.

Why it matters at the device level

The practical consequences land on anyone responsible for patch latency or security auditability of an Android platform. Because much vendor logic lives in modules that bind to hooks rather than in the common kernel itself, security updates to the common kernel and updates to vendor modules move on separate tracks, on separate signing keys, under separate owners. Upstream discussion has reflected unease about this: kernel maintainers including Kees Cook have raised questions about how out-of-tree hook and module-ABI surfaces affect the auditability of a shipped kernel, and engineer Todd Kjos has discussed the retirement of hooks as their backing functionality graduates into mainline — though the total hook population has not meaningfully collapsed, since each hook typically backs a feature a shipping OEM depends on.

For engineers working on Android device platforms, supply-chain integration or third-party device certification, this is a structural fact of the job rather than an abstraction: any device in the pipeline effectively runs a small, vendor-signed kernel extension layer whose contents are not in the common tree.

The honest summary is the one LWN's coverage supports. GKI solved kernel fragmentation as a build problem — there is, at last, one image to certify and update. As an architecture problem, fragmentation moved into the hook surface, where it is easier to manage but nowhere near gone.

Source: LWN.net, "Vendor hooks in the Android kernel" (subscriber-supported). Developers can inspect the hook surface directly in the Android Common Kernel under include/trace/hooks/.


LWN.net 於其訂戶付費牆後發表了一篇分析,探討儘管多年來一直致力於將 OEM 及晶片組的分叉收歸單一共享映像,廠商 hook 如何最終成為 Android 內核中樹外(out-of-tree)分歧得以存活的通道。

核心矛盾其實很簡單。Android 的 Generic Kernel Image(GKI)計劃承諾終結長期以來每部裝置各自附送專屬分叉內核的問題:裝置製造商將基於同一個經認證的通用內核映像進行開發,其餘差異則透過官方認可的擴展點來表達,而非直接修改內核源碼。這項承諾已部分兌現。LWN 文章所記錄的,正是大量分歧得以繼續存在的機制。

由分叉源碼樹轉為 hook 符號

在 Android 大部分歷史中,廠商一直攜帶大量樹外修改:排程器調校、電源管理改動、驅動整合及安全修補,全部以私有 source diff 形式維護,每次內核新版本發布都必須重新 rebase。GKI 的設計目標正是縮減這個差異。大規模推行始於 Android 11;而強制要求則在 Android 12 配合 GKI 2.0 落實,統一採用 5.10 LTS 內核。

時至今日,廠商改動的首選形式已不再是直接修改內核,而是使用 hook。在 Android Common Kernel 樹中,hook 透過 DECLARE_HOOK 及 DECLARE_RESTRICTED_HOOK 巨集宣告,相關宣告存放於 include/trace/hooks/ 之下。這些巨集會生成可調用符號,歸入 android_vh_*(vendor hook)及 android_rvh_*(restricted vendor hook)兩個命名空間,供樹外模組——通常是隨特定 SoC 或周邊裝置附送的二進制驅動 blob——註冊 callback。

兩類 hook 之間的不對稱性十分關鍵。一般 vendor hook 廣泛可供調用;restricted hook 則設有門檻,只允許第一方模組掛接,由 GKI 模組簽署允許清單強制執行——即 abi_gki_aarch64 中的各項條目,決定出貨映像會載入哪些模組。這是整套安排中的隱性治理層:hook 界面不僅僅是技術 API,更是一個帶有權限管理的界面。

對裝置層面的影響

實際後果落在每一位負責 Android 平台修補時效或安全審計的人士身上。由於大量廠商邏輯存在於掛接 hook 的模組之中,而非通用內核本身,通用內核的安全更新與廠商模組的更新因而各行其道,使用不同的簽署金鑰,由不同負責人管理。上游討論已反映對此情況的憂慮:包括 Kees Cook 在內的內核維護者曾就樹外 hook 及模組 ABI 界面如何影響已出貨內核的可審計性提出質疑;工程師 Todd Kjos 亦曾談及隨著相關功能逐漸進入 mainline,hook 應予淘汰——然而 hook 總數至今並未顯著減少,因為每個背後通常都對應一項出貨 OEM 所依賴的功能。

對於從事 Android 裝置平台、供應鏈整合或第三方裝置認證的工程師而言,這是工作中的結構性事實,而非抽象概念:流程中任何一部裝置實質上都在運行一個小型、經廠商簽署的內核擴展層,而其內容並不在通用源碼樹之中。

誠實的總結正是 LWN 報導所支持的觀點。GKI 以構建問題的角度解決了內核碎片化——終於只有一個映像需要認證及更新。但以架構問題的角度而言,碎片化轉移到了 hook 界面之中,在那裡較易管理,卻遠遠未臻消失。

來源:LWN.net,"Vendor hooks in the Android kernel"(訂閱者支持)。開發者可直接在 Android Common Kernel 的 include/trace/hooks/ 目錄中檢視 hook 界面。