ソースコード・セキュリティ監査

vendored lha ソースの多角的監査: 危険な関数の grep、ライブラリ依存面、ランタイム権限、 テンポラリファイル安全性、メンテナの帰属チェーン。

純粋な静的解析 — 実行なし、ネットワークなし、 ファジングなし。各 grep はリポジトリのルートから そのままコピー&ペーストで再現可能。

→ 性能比較 · ↑ サイト

五つの監査軸

ソースは自己完結した C プログラム。 libiconv(デフォルト off、musl-static は 組み込み版を使用)以外に configure 時のオプション依存は ない。五つの独立した軸で監査:

  1. ネットワーク面。ランタイムで socket を開いたり、 DNS を引いたり、HTTP/SFTP を話したりするか?
  2. サブプロセス面。fork / exec / system / popen で他のバイナリを 起動するか?
  3. >権限昇格。setuidsetgidchrootmount を呼ぶか?
  4. >メモリ安全でないプリミティブ。CWE フラグ付き関数 (strcpysprintfgetsscanf)のうちどれが使われているか? 使われている場合、長さチェックされているか?
  5. >テンポラリファイル競合。伸長時に原子的 mkstemp(3) を使うか、競合可能な mktemp(3) か?

各軸が一つの grep -nE に対応する。結果は 次節。

監査結果

  1. >ネットワーク呼び出し:なし
    grep -nE '\b(socket|connect|inet_|gethostbyname|getaddrinfo|curl|http_send)\b' upstream/lha/src/*.c
    ゼロ一致。lha は socket を開かず、DNS を引かず、HTTP を 話さず、URL 処理ライブラリを呼びません。リンカシンボル テーブルにもネットワーク系ライブラリは存在しない; ランタイムは完全オフライン。
  2. >サブプロセス呼び出し:なし
    grep -nE '\b(fork|vfork|system|exec[pvl][ep]?|popen|daemon)\b' upstream/lha/src/*.c
    ゼロ一致。lha は shell out しない。外部圧縮ツールは 使わない(自前実装)、xz への pipe もしない、 外部の署名・検証ツールも呼び出さない。stdio.h への呼び出しはアーカイブファイル自体の読み書きのみ。
  3. >権限昇格:なし
    grep -nE '\b(setuid|setgid|seteuid|setegid|setreuid|chroot|mount|acl_set)\b' upstream/lha/src/*.c
    ゼロ一致。lha は呼び出し元の umaskextract.c 内の umask(022))で 展開し、権限を昇格しない。シンボリックリンクの展開は ロックダウンされている:lhext.c はシンボリック リンクが展開先のパスを越えて辿ることを阻止し、展開先 外を指すアーカイブのシンボリックリンクを拒否する。これは まさに CVE-2022-1027 系のような旧 archiver が持っていた 脆弱性クラス — lha は該当しない。
  4. >メモリ安全でないプリミティブ:strcpy 8 箇所、すべて境界チェック済み;sprintf/gets/scanf ゼロ
    grep -nE '\b(strcpy|sprintf|gets|scanf)\s*\(' upstream/lha/src/*.c

    8 箇所の strcpy 呼び出し点。 sprintf / gets / scanf はゼロ。 8 箇所の内訳:

    • 8 箇所のうち 7 箇所は直前で長さチェック。 それぞれソース中に /* ok */ 注釈あり — 上流メンテナのレビューマーカー。
    • 残り 1 箇所 — strcpy(p, buf) in util.c:126 — は strdup パターン:pstrlen(buf)+1 バイトで malloc 直後、つまりちょうどもう 1 バイト余裕がある。バッファオーバーランなし。

    現代の lha 代替(lz4、zstd、7z)は同様に大きなプリミティブ 面を持つが、現在の sanitizer ファジング調整済み。lha は 古い分、危険呼び出し点の数が少なく、個別にチェック済み。

  5. >テンポラリファイル: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) は deprecated / 危険な版。lha は 使わない。

ランタイムで実際にリンクされるもの

静的バイナリ配布版がリンクするのは:

libcurl / libssl / libxml2 / libsystemd なし。musl-static ビルドでは上記 すべて単一バイナリに同梱 — これが x eget use lha のインストール結果。

メンテナ帰属チェーン

五軸の grep はソースが何をするかを示すだけ。バイナリが 実際に何であるかを確認するには、ソース帰属を 30 年・7 メンテナ遡る必要がある — いずれも公開 LZH/LHA ナレッジグラフ上:

各貢献者の変更はヘッダに帰属として残され、upstream/lha/ 内の tar は jca02266/lha86094cb とビット単位一致。当リポジトリは lha 本体を保守せず、静的バイナリのみをビルドする。

結論

lha バイナリは配布・実行ともに安全。攻撃面は:

「ユーザー指定のバイナリファイルを読み込み、ヘッダを パースし、内部のパスとバイトを書き出す」

ネットワークなし、サブプロセスなし、権限境界の横断なし、 メモリ安全でないプリミティブは個々に境界チェック済み。 テンポラリファイルパスは mkstemp(3) で原子的。 上流帰属チェーンは 30 年・7 メンテナ、すべて公開 LHA ナレッジグラフ上、隠れた書き換え者なし。