← 開発ノート

Fragnesia CVE-2026-46300:Linuxカーネルの修正と稼働カーネルの証拠

この記事の目次

Fragnesia(CVE-2026-46300)は、Linuxカーネルのローカル権限昇格の脆弱性です。 適切なディストリビューションとカーネル系列の修正を適用し、稼働中のカーネルで有効になっていることを検証します。Ubuntuの公式説明は、該当条件下でコンテナ脱出の可能性もあるとしています。Linuxであることは、すべてのシステムの影響が同じことを意味しません。

インターネット上の攻撃者が直接rootを得られますか?

このCVEはローカル権限昇格です。攻撃者がシステム上でコードを実行し、脆弱なカーネル経路へ到達できることが必要です。Webアプリケーションのリモートコード実行とは区別します。CISAの公式KEVデータは、PHP2ShellのCVE-2026-109618とCVE-2026-109619を連鎖させるリスクを記録しています。PHPランタイムのパッチ適用とホストカーネルのパッチ適用を個別に確認します。

元のCVEレコードは、ソケットバッファの結合中に共有ページフラグメントのマーカーが失われると説明しています。その後のESP処理が共有ページを専用ページと誤認し、その場で変更する可能性があります。このCVEは2026年5月23日に公開され、CISAは10月28日にKEVへ追加しました。十月に初めて導入された欠陥ではありません。KEVの10月31日期限は、すべてのサービス共通の変更期限とせず、適用される指令の範囲で解釈します。

どのカーネルを更新する必要がありますか?

修正範囲を一つのCVEだけに絞らないでください。Ubuntuセキュリティチームの注記は、CVE-2026-43284と関連する修正をまとめて提供するよう勧めています。別のフラグメント転送経路の修正は、CVE-2026-43503としても追跡されています。CVE-2026-43284は、Dirty Frag系列の別項目です。供給元の完全な修正済みパッケージを優先します。選択した一つのコミットを適用しても、完了とは確定できません。

以下は、2026年10月31日に確認したUbuntuのlinuxソースパッケージの修正しきい値の抜粋です。まず、インストール済みバイナリパッケージをソースパッケージとカーネル系列へ対応付けます。

Ubuntuリリース linuxの修正しきい値
22.04 LTS 5.15.0-181.191
24.04 LTS 6.8.0-124.124
26.04 LTS 7.0.0-22.22

AWS、Azure、HWE、OEM、リアルタイムカーネルに、このしきい値を流用しないでください。パッケージ名、サポート系列、供給元のバックポートが異なります。RHELでは、Red Hatの通知にある製品状態とリンク先のRHSAに従います。AWS自身の通知は、espintcp設定に基づき、Amazon LinuxとBottlerocketが影響を受けないことを説明しています。この記述を、EC2上の任意の独自カーネルや他のディストリビューションへ拡張しないでください。

まず稼働カーネルの証拠を収集する

Linuxかを確認して稼働カーネルとOSを読み、dpkg-queryがあれば二つのパッケージ名を照会し、失敗を区別して修正状況を判定せず証拠を出力します

図は以下の収集コードに対応しています。Python 3.10以降が必要です。dpkg-queryを利用できるLinuxでは、稼働カーネルのリリースから導出した二つのパッケージ名だけを照会します。ネットワークアクセス、管理者権限、モジュールの読み込み、システム変更は不要です。脆弱性検出器でも、パッチ適用完了の判定でもありません。 証拠不足を安全と報告することはありません。

kernel-evidence.py

import json
import platform
import shutil
import subprocess


def collect():
    result = {"patch_status": "not-assessed", "scope": "current-execution-context"}
    if platform.system() != "Linux":
        return {**result, "error": "linux-required"}, 2
    try:
        release = platform.release()
        distro = platform.freedesktop_os_release()
    except OSError:
        return {**result, "error": "os-evidence-unavailable"}, 2
    result.update(running_kernel=release,
                  os={key: distro.get(key) for key in ("ID", "VERSION_ID")}, queries=[])
    command = shutil.which("dpkg-query")
    if not command:
        return {**result, "package_query": "dpkg-query-unavailable"}, 0
    result["package_query"] = "dpkg-query"
    for name in ("linux-image-" + release, "linux-image-unsigned-" + release):
        row = {"package": name}
        try:
            answer = subprocess.run(
                [command, "-W", "-f=${Package}\t${Version}\t${db:Status-Status}\n", name],
                capture_output=True, text=True, timeout=5, check=False)
        except (OSError, subprocess.TimeoutExpired):
            row["state"] = "query-error"
        else:
            fields = answer.stdout.rstrip("\n").split("\t")
            if answer.returncode == 1:
                row["state"] = "not-found"
            elif answer.returncode != 0:
                row["state"] = "query-error"
            elif len(fields) != 3 or fields[0] != name or not fields[1]:
                row["state"] = "unexpected-output"
            elif fields[2] != "installed":
                row["state"] = "not-installed"
            else:
                row.update(state="installed", version=fields[1])
        result["queries"].append(row)
    return result, 0


if __name__ == "__main__":
    evidence, status = collect()
    print(json.dumps(evidence, ensure_ascii=False, indent=2, sort_keys=True))
    raise SystemExit(status)
python3 kernel-evidence.py

Linux以外の環境、またはOSの証拠を取得できない場合は、終了コード2を返します。Linuxでの収集が完了しても、個別のパッケージ照会は失敗する場合があります。package_queryと各stateを読んでください。終了コード0はパッチ適用完了を意味しません。この二つの照会では、RPMや独自カーネルの所有パッケージは特定できません。

以下の出力は、合成した入力で実行・確認したものです。Ubuntu 24.04、稼働カーネル6.8.0-124-generic、最初のパッケージはインストール済み、二つ目は未インストールという条件です。本番Ubuntuホストの証拠ではありません。実行確認は、この出力と照会失敗の分岐を再現するものであり、実際のカーネルの脆弱性、修正の適用、悪用をテストするものではありません。

{
  "os": {
    "ID": "ubuntu",
    "VERSION_ID": "24.04"
  },
  "package_query": "dpkg-query",
  "patch_status": "not-assessed",
  "queries": [
    {
      "package": "linux-image-6.8.0-124-generic",
      "state": "installed",
      "version": "6.8.0-124.124"
    },
    {
      "package": "linux-image-unsigned-6.8.0-124-generic",
      "state": "not-found"
    }
  ],
  "running_kernel": "6.8.0-124-generic",
  "scope": "current-execution-context"
}

コンテナ内では、OSとパッケージデータベースがコンテナに属し、カーネルは共有ホストに属する場合があります。ホストまたはVMの管理経路で改めて収集します。新たにインストールしたカーネルパッケージも、現在稼働しているカーネルと異なる場合があります。このコードは現在のリリースに対応する名前だけを照会し、インストール済みカーネルをすべて列挙するものではありません。パッケージ署名、整合性、livepatchの状態も検証しません。

パッチ適用後に何を検証すべきですか?

  1. 資産のディストリビューション、稼働カーネル、パッケージ系列を、供給元のCVEまたはセキュリティ通知へ対応付けます。異なる系列のバージョンを単純な文字列比較で比べないでください。
  2. サポート対象のリポジトリやイメージから修正済みパッケージを適用し、ノードを段階的に置き換えるか再起動します。Ubuntu USN-8388-1は、標準更新後の再起動を求め、サードパーティーカーネルモジュールのABI変更にも言及しています。livepatchだけに依存する場合は、そのCVEと稼働カーネルについて、サポートと実際の適用を個別に検証します。
  3. 再起動後に同じ証拠を収集し、有効なカーネルを供給元の修正証拠と比較して、サービスの健全性、ストレージ、ネットワークを確認します。KubernetesのPodを再起動するだけでは、ノードのカーネルは置き換わりません。
  4. 初期侵入と永続化の可能性も調査します。パッチ適用の成功は、既存のWebシェルや盗まれた認証情報がないことを証明しません。

即座に更新できない場合は、Ubuntuの暫定緩和策と供給元の指示を確認します。モジュール制限は、VPN/IPsecなどの機能と競合する場合があります。既に読み込まれた経路や組み込みの経路は別の評価が必要です。モジュール一覧にないことは、影響を受けない根拠になりません。影響経路を減らし、信頼できないコードを制限することは暫定措置であり、修正済みパッケージの適用を代替しません。

コメント

GitHubで見る ↗