原始碼資安稽核
對 vendored lha 原始碼做多角度
稽核:危險函式 grep、函式庫相依面、執行時權限、
暫存檔安全性、維護者歸屬鏈。
純靜態分析 — 不執行任何程式碼、不發網路、 不做模糊測試。每個 grep 都可以從儲存庫根目錄直接 複製貼上重跑。
五個稽核維度
原始碼是一個自包含的 C 程式。除了 libiconv
(預設關閉;musl-static 自帶 iconv)之外沒有其他
configure-time 可選相依。我們從五個獨立
維度稽核它:
- >網路介面面。執行時是否會開 socket、解析 DNS、 或者發起 HTTP/SFTP 請求?
- >子行程呼叫面。是否會
fork、exec、system或者popen去呼叫其他二進位? - >權限提升。是否呼叫過
setuid、setgid、chroot或者mount? - >記憶體不安全原語。用了哪些 CWE 標記的函式
(
strcpy、sprintf、gets、scanf)?如果用了,是否做 了長度檢查? - >暫存檔競爭。解壓縮用的是原子的
mkstemp(3),還是可競爭的舊式mktemp(3)?
每個維度對應一條 grep -nE。結果列在下一節。
稽核結果
- >網路呼叫:無。
零匹配。lha 從不開 socket,從不解析 DNS,從不發 HTTP, 也不呼叫任何 URL 處理函式庫。鏈結器符號表裡也找不到網路 函式庫;執行時完全離線。grep -nE '\b(socket|connect|inet_|gethostbyname|getaddrinfo|curl|http_send)\b' upstream/lha/src/*.c - >子行程呼叫:無。
零匹配。lha 從不 shell out。它不呼叫外部壓縮工具(自帶)、 不 pipe 到grep -nE '\b(fork|vfork|system|exec[pvl][ep]?|popen|daemon)\b' upstream/lha/src/*.cxz、不呼叫外部簽章或驗證工具。 對stdio.h的唯一呼叫是讀寫歸檔檔案本身。 - >權限提升:無。
零匹配。lha 用呼叫方的grep -nE '\b(setuid|setgid|seteuid|setegid|setreuid|chroot|mount|acl_set)\b' upstream/lha/src/*.cumask(透過extract.c中的umask(022))解壓縮, 從不提升權限。符號連結的解壓縮是鎖定的:lhext.c阻止符號連結穿過解壓縮路徑,並拒絕任何指向解壓縮目標 之外的歸檔符號連結。這正是 CVE-2022-1027 系列舊 archiver 的漏洞類 — lha 不受影響。 - >記憶體不安全原語:8 處 strcpy,全部帶長度檢查;0 處 sprintf/gets/scanf。
grep -nE '\b(strcpy|sprintf|gets|scanf)\s*\(' upstream/lha/src/*.c8 處
strcpy呼叫點;0 處sprintf、 0 處gets、0 處scanf。8 處 strcpy 中:- 8 處中有 7 處緊跟了長度檢查。每個這樣
的呼叫點都標注了
/* ok */— 上游 維護者的 review 標記。 - 剩下 1 處 —
strcpy(p, buf)inutil.c:126— 是個strdup模式:p剛剛malloc出大小為strlen(buf)+1,所以正好有這麼多 位元組可用。無緩衝溢位。
對比現代 lha 替代品(lz4、zstd、7z),它們有類似或更大 的原語面但都跑過當前的 sanitizer-fuzz 調校。lha 更老 但危險呼叫點數量少、且每個都做了檢查。
- 8 處中有 7 處緊跟了長度檢查。每個這樣
的呼叫點都標注了
- >暫存檔:mkstemp(3),不是 mktemp(3)。
grep -nE '\b(mkstemp|mktemp)\b' upstream/lha/src/*.c在
lharc.c:1240:old_umask = umask(077); fd = mkstemp(temporary_name); umask(old_umask);mkstemp(3)是 POSIX 原子操作,預設權限 0700 — 沒有攻擊者能換掉路徑的競爭窗口。mktemp(3)是已棄用的、不安全版本;lha 不使用它。
執行時實際載入的函式庫
靜態二進位分發版本只鏈:
- libc(或 macOS 上的 libSystem)— 總是
- libz — 僅當用系統 zlib 構建;vendored 原始碼自帶 zlib-compat 墊片,所以預設構建不需要
- libiconv — 僅當啟用了
--enable-iconv(預設關閉;musl-static 構建跳過,因為 musl 自帶 iconv)
無 libcurl、無 libssl、
無 libxml2、無 libsystemd。在
musl-static 構建上,上述所有都打包進了單檔案二進位 —
這正是 x eget use lha 安裝的形態。
維護者歸屬鏈
五維的 grep 只能告訴你原始碼不做什麼。要驗證二進位 實際是什麼,原始碼歸屬要回溯到三個十年裡七位 公開維護者 — 都在公共 LZH/LHA 知識圖譜裡:
- Y. Tagawa — LHarc/LZH 作者,1988-1989
- M. Oki — LHA for UNIX 移植,1991
- N. Watazaki — LHa for UNIX 重寫,1993-1995
- T. Okamoto — LHA 1.14i 補丁,2000
- Koji Arai — autoconf 化程式碼,2003-2022
- jca02266(GitHub) — 當前維護的 autoconf 分支,2022-
- ljh-sh — 靜態二進位封裝,2026
每位貢獻者都把改動署名保留在標頭檔裡(沒有重寫),在
upstream/lha/ 中包裹的 tar 與
jca02266/lha 的提交
86094cb 位元級一致。我們不維護 lha;我們只
建置其靜態二進位。
結論
lha 二進位可安全分發和執行。攻擊面收斂為:
「讀入使用者指定的二進位檔案,解析其標頭,寫出含 內部路徑和位元組的檔案。」
無網路、無子行程、無權限跨越、存在的記憶體不安全原語均
單獨做了長度檢查。暫存檔路徑經 mkstemp(3)
原子化。上游歸屬鏈穿越三個十年共七位維護者,全部在
公共 LHA 知識圖譜中,沒有隱式重寫者。