libextractor 提權漏洞:外掛路徑變數未查特權
oss-security · 2026-09-26
GNU libextractor 決定要去哪裡找外掛時,只看 LIBEXTRACTOR_PREFIX 這個環境變數怎麼設,卻從不檢查呼叫它的程式是不是以 setuid/setgid 身分在跑——這代表任何連結這顆函式庫的特權程式,都可能被騙著去載入攻擊者準備好的共享函式庫。這個問題登記為 CVE-2026-100310,由 Haitam Lazaar 於 2026 年 9 月 25 日在 oss-security 首度揭露,Simon McVittie 隔天在後續討論串補充了分析與爭議點。
漏洞機制
問題出在 src/main/extractor_plugpath.c 的 get_installation_paths():程式直接呼叫 getenv("LIBEXTRACTOR_PREFIX") 取得外掛搜尋路徑,完全沒有判斷目前的真實使用者(uid)與有效使用者(euid)是否不同。在一般情況下這無傷大雅,但一旦有 setuid root 的程式連結了 libextractor,攻擊者就能在提權那一刻插手。
攻擊流程照公告描述分五步:攻擊者先準備一個目錄,裡面放一顆惡意的共享函式庫(.so);接著把 LIBEXTRACTOR_PREFIX 指向這個目錄;當 setuid 程式執行並呼叫到 libextractor 時,函式庫會照著這個路徑去載入外掛;惡意函式庫的建構子(constructor)會在程式已經取得高權限之後、於載入階段就先被執行;建構子裡只要呼叫 setuid(0),就完成了從一般使用者到 root 的提權。整條鏈不需要記憶體錯誤或任何複雜的漏洞利用技巧,純粹是「該檢查而沒檢查」的信任邊界問題,跟 LD_PRELOAD/LD_LIBRARY_PATH 這類已知會被 glibc 動態載入器攔截的變數是同一類風險,只是 libextractor 自己重新實作了一套路徑決策邏輯,卻沒有補上同等的防護。
McVittie 的回覆討論了一個更根本的爭議:libextractor 本身是不是有義務替呼叫者的 setuid 誤用負責,還是應該由那些把 libextractor 連結進特權程式的維護者,先確認自己選用的函式庫有沒有做這種防護。這場討論沒有結論,但實務上的修法方向已經定案——library 端補上檢查比要求所有下游呼叫者都寫對安全一致做法更省事。
受影響版本
libextractor1.16 之前的所有版本(含 0.x 到 1.15)都受影響。- 影響前提是該版本被連結進以
setuid或setgid執行的程式;純使用者權限下呼叫 libextractor 不構成提權風險,但仍然可能被用來載入非預期程式碼。 - 公告未附 CVSS 分數,僅以文字描述定性為本機權限提升。
修補與緩解
上游已在 1.16 版修正,對應提交是 6edfa653c048800e24a17f7e8cc2bb42659b8d01。公告與討論串都沒有貼出完整 diff,但描述的方向是:修補後的程式碼會先確認目前是否處於特權執行環境,若是,就不再信任外部可控的 LIBEXTRACTOR_PREFIX,退回內建的預設安裝路徑。
如果暫時無法升級,該做的事是先盤點自己有哪些 setuid/setgid 程式連結了 libextractor——常見於檔案編目、桌面搜尋索引一類會替其他使用者掃描檔案內容的工具。在能升級之前,可以在呼叫 libextractor 前主動清除或鎖定 LIBEXTRACTOR_PREFIX,或者乾脆重新檢視這些程式是否真的需要用 setuid 執行;把權限提升的範圍縮小,往往比等每一顆被連結的函式庫都補齊防呆更可靠。
這起事件也是提醒:套件維護者不能只檢查自己程式碼裡有沒有直接讀取危險環境變數,還得往下追一層,確認每一顆被連結進特權程式的第三方函式庫,是不是也用同樣嚴謹的態度在處理外部可控輸入。libextractor 在這次修補之前,顯然沒有把自己放進「可能被 setuid 呼叫」的威脅模型裡。