このリリースは 15.18 からの修正リリース(2026年 8月 13日リリース)です。
15.X からのアップデートではダンプ、リストアは不要です。
しかしながら、最初の 3項目のセキュリティ修正は、設定の修正やデータのクリーンアップが必要となるかもしれません。また、以下に記載の修正項目に該当する GiSTインデックスがある場合には、インデックス再構築が必要となります。
さらに、15.14 よりも前のバージョンからアップデートする場合には、15.14のリリース情報も参照してください。
PostgreSQL 15.18 から 15.19 への変更点
18.6, 17.11, 16.15, 15.19, 14.24 の各バージョンが同時にリリースされており、本ページでは共通の記載としています。各修正項目が適用されるバージョン系列番号を項目末尾に括弧書きで記載しています。
- ロジカルデコーディングの出力プラグインが厳格化されました。新たな設定パラメータoutput_plugin_librariesでの指定が必要となりました。(CVE-2026-6471) (Jacob Champion) (18)(17)(16)(15)(14)
- contrib/pgcryptoのPGP暗号化がサポートされない暗号化方式を検出するように、修正されました。(CVE-2026-14663) (Daniel Gustafsson) (18)(17)(16)(15)(14)
- psqlがスクリプト化された「COPY ... FROM STDIN」コマンドに続くインラインデータを、COPY開始時のエラーであっても、読み飛ばすように修正されました。(CVE-2026-6464) (Tom Lane) (18)(17)(16)(15)(14)
- EXECUTEやFETCHを実行するポータルの出力行型についてクロスチェックを行うようになりました。(CVE-2026-16239) (Robert Haas) (18)(17)(16)(15)(14)
- to_char()で、長いタイムゾーン省略形によるバッファオーバーランが修正されました。(CVE-2026-14669) (Tom Lane) (18)(17)(16)(15)(14)
- 正規表現によるマッチ、分割の関数で、バッファオーバーランが修正されました。(CVE-2026-14664) (Masahiko Sawada) (18)(17)(16)(15)(14)
- ascii()関数が不正な入力に対して頑健になりました。(CVE-2026-18024) (Michael Paquier) (18)(17)(16)(15)(14)
- pg_restore_attribute_stats()関数でのマルチ範囲型の処理が修正されました。(CVE-2026-16238) (OpenAI Security Research Team) (18)(17)(16)(15)(14)
- scalarineqsel()が、tid型と想定される定数を実際にそうであるか検査するようになりました。(CVE-2026-14668) (Tom Lane) (18)(17)(16)(15)(14)
- tsvector型とtsquery型の実装コードが(個々の要素、全体の長さの両面で)きわめて長い値に対して頑健になりました。(CVE-2026-14662) (Tom Lane) (18)(17)(16)(15)(14)
- 「FUNC_MAX_ARGS」を超える関数引数を処理する必要がない、と誤って想定していた様々な箇所が修正されました。(CVE-2026-14679) (Tom Lane) (18)(17)(16)(15)(14)
- internal型を引数や戻り値とする関数のSQLからの呼び出しを拒否するようになりました。(CVE-2026-14680) (Tom Lane) (18)(17)(16)(15)(14)
- ALTER TABLEコマンドで再構築されたとき、拡張統計オブジェクトの所有者が保たれるようになりました。(CVE-2026-6469) (Masahiko Sawada) (18)(17)(16)(15)(14)
- EXTRACT()関数呼び出しを逆パースするときに、必要であればフィールド名をクォートするようになりました。(CVE-2026-15741) (Nathan Bossart) (18)(17)(16)(15)(14)
- これまで検査ができていなかった個所について、データ型に対する「USAGE」権限を検査するようになりました。(CVE-2026-6470) (Nathan Bossart) (18)(17)(16)(15)(14)
- 行単位セキュリティ(RLS)に対して、ロールに依存したキャッシュされたプランを、ロール変更後に無効化するようになりました。(CVE-2026-14666) (Ilya Staroverov, Shinya Kato, Nathan Bossart) (18)(17)(16)(15)(14)
- 直接のSSL接続の後のGSSEncRequestメッセージを拒否するようになりました。(CVE-2026-14681) (Michael Paquier) (18)(17)(16)(15)(14)
- モックのSCRAM認証シークレットがより本物らしくなりました。(CVE-2026-14672) (Nathan Bossart) (18)(17)(16)(15)(14)
- ecpgアプリケーションでの範囲外書き込みが修正されました。サーバから不正なbytea型データを受け取ることで引き起こされます。(CVE-2026-16241) (Michael Paquier) (18)(17)(16)(15)(14)
- psqlの「\unrestrict」コマンドの引数でバッククォート展開をしないようになりました。(CVE-2026-18408) (Nathan Bossart) (18)(17)(16)(15)(14)
- pg_dumpにおいてpg_proc.protrftypesのエントリ数がFUNC_MAX_ARGSを超えないという前提が取り除かれました。(CVE-2026-19385) (Tom Lane) (18)(17)(16)(15)(14)
- tieされたPerlの配列やハッシュに対して、PL/Perlが堅牢化されました。(CVE-2026-14670) (Tom Lane) (18)(17)(16)(15)(14)
- PL/PerlおよびPL/Tclにおけるメモリ割り当て計算時の整数オーバーフローが修正されました。(CVE-2026-14677) (Heikki Linnakangas) (18)(17)(16)(15)(14)
- contrib/amcheckの関数がインデックス式を実行する前にsearch_pathを制限するようになりました。(CVE-2026-14673) (Noah Misch) (18)(17)(16)(15)(14)
- contrib/fuzzystrmatchのlevenshtein()およびlevenshtein_less_equal()関数における整数オーバーフローが修正されました。(CVE-2026-15742) (Nathan Bossart) (18)(17)(16)(15)(14)
- contrib/pg_stat_statementsにおけるバッファオーバーランが修正されました。(CVE-2026-14676) (Alvaro Herrera) (18)(17)(16)(15)(14)
- contrib/pg_trgmのGiST picksplit関数におけるデータ型エラーが修正されました。(CVE-2026-14678) (Heikki Linnakangas) (18)(17)(16)(15)(14)
- contrib/refintのプランキャッシュが削除されるようになりました。(CVE-2026-14671) (Ayush Tiwari) (18)(17)(16)(15)(14)
- 並列GINインデックスの構築時に、テーブルのpg_class.reltuples値が正しく更新されるようになりました。 (Jan Nidzwetzki, Tomas Vondra) (18)
- 非同期のAppendプランノードを再スキャンする際の、非同期読み取りの不適切な処理が修正されました。 (Alexander Korotkov, Gleb Kashkin, Etsuro Fujita) (18)(17)(16)(15)(14)
- RANGEパーティションテーブルにおけるパーティションプルーニングの不具合が修正されました。 (David Rowley) (18)(17)(16)(15)(14)
- 結果リレーションのプルーニング後に、ModifyTableプランノード内の外部データラッパーの状態を正しく更新するようになりました。 (Ayush Tiwari, Rafia Sabih) (18)
- 「BEFORE UPDATE」トリガーを持つテーブルに対して、「RETURNING OLD」を指定したUPDATE文で発生していた並行更新の処理漏れが修正されました。 (Dean Rasheed) (18)
- 複数の結合キーと多数のNULL値が存在する場合のハッシュ結合の性能問題が修正されました。 (David Rowley) (18)
- RETURNING句の式における括弧で囲まれた「OLD」や「NEW」の解析処理が修正されました。 (Marko Grujic) (18)
- value IN (array)式に対するプランナのNULL許容性および厳密性チェックが修正されました。 (Ayush Tiwari) (18)(17)(16)(15)(14)
- 不適切な結合削除のロジックが修正されました。 (Matheus Alcantara, Richard Guo) (18)(17)(16)
- 結合の削除処理において、PlaceHolderVarsのクリーンアップがより徹底されるようになりました。 (Richard Guo, Arne Roland) (18)
- コンテナデータ型(配列、複合型、範囲型)の等価比較におけるハッシュ可能性に関する漏れていたチェックが追加されました。 (Andrei Lepikhov, Tom Lane) (18)(17)(16)(15)(14)
- プランナが、異なる等価性ルールを持つグループ化ステップより下位へ、WHERE句をプッシュダウンすることを避けるようになりました。 (Richard Guo) (18)
- 「EXCLUDE」句を指定している、または「ORDER BY」を指定していない、COUNTウィンドウ関数の誤った最適化が修正されました。 (Chengpeng Yan, David Rowley) (18)(17)(16)(15)
- プランナが"char"型の列の統計情報を参照する際に、予期せぬエラー「ERROR: cache lookup failed for collation 0」が発生する障害が修正されました。 (Feng Wu) (18)
- 複数階層のパーティションが存在する場合でも、ALTER TABLEのALTER COLUMN ... DROP EXPRESSIONが正常に動作するよう修正されました。 (Alberto Piai) (18)(17)(16)(15)(14)
- 排他制約であるインデックスのパーティションをアタッチする処理の不具合が修正されました。 (Japin Li) (18)(17)
- ALTER CONSTRAINTを使用して、パーティションテーブルのNOT NULL制約にNO INHERITを設定することができないように修正されました。 (Andreas Karlsson) (18)
- ルールの名前を「_RETURN」に変更できないように修正されました。 (Tom Lane) (18)(17)(16)(15)(14)
- DROP OWNED BYにおいて、ロールメンバーシップへのロックの解放漏れが修正されました。 (Jeff Davis) (18)(17)(16)
- EXPLAINがSQL/JSONの集約関数をデパースするときに予期せぬエラーを出すことがあり、修正されました。 (Richard Guo) (18)(17)(16)
- 遅延一意性制約のインデックスに対してREINDEX CONCURRENTLYを使用した場合の不具合が修正されました。 (Nitin Motiani) (18)(17)(16)(15)(14)
- 非決定論的照合順序でバックスラッシュ(\)を使用したLIKE句のマッチングの不具合が修正されました。 (Nitin Motiani, Tom Lane) (18)
- LIKE句や正規表現の完全一致パターンのインデックススキャン最適化の不具合が修正されました。 (Jelte Fennema-Nio) (18)
- to_date() におけるローカライズされた月名、曜日名のマッチング処理が修正されました。 (Heikki Linnakangas) (18)(17)(16)(15)(14)
- ギリシャ文字の語末形のシグマに対する大文字小文字の変換のルールが修正されました。 (Jeff Davis) (18)
- ハングルU+11A7(TBASE)のNFC再合成における誤りが修正されました。 (Diego Frias, Michael Paquier) (18)(17)(16)(15)(14)
- 大文字小文字を区別しない類義語の辞書において、出力する語彙素が切り捨てられる不具合が修正されました。 (Jeff Davis) (18)(17)(16)(15)(14)
- 大文字小文字変換処理において、途中で途切れたUTF-8文字への対処が修正されました。 (Jeff Davis) (18)(17)
- hash_record_extended()のバグが修正されました。 (Man Zeng) (18)(17)(16)(15)(14)
- 公開可能なテーブルが並行して削除された場合に、pg_get_publication_tables()が失敗する不具合が修正されました。 (Bharath Rupireddy) (18)(17)(16)
- VARIADIC NULL を指定した場合に、satisfies_hash_partition() がクラッシュする不具合が修正されました。 (Robert Haas) (18)(17)(16)(15)(14)
- tsvector_filter() および関連する関数で、不正な重みに関するエラーを、より明確かつ一貫した形で報告するよう修正されました。 (Ewan Young) (18)(17)(16)(15)(14)
- uundv7()関数で範囲外のタイムスタンプとなるシフト値を拒絶するようになりました。 (Baji Shaik) (18)
- xpath()関数でnamestapeノードの処理が修正されました。 (Michael Paquier) (18)(17)(16)(15)(14)
- jsonpathの「.decimal」メソッドが、精度やスケールの指定が正しくない場合でもERRORを出さないように、修正されました。 (Ewan Young) (18)(17)
- 「IS JSON」や「JSON()」等の構文が、text型へのキャストを持たない文字列型の引数を与えられたときの、NULLポインタによるクラッシュが修正されました。 (Ayush Tiwari) (18)(17)(16)
- 「SQL/JSON」の「ON EMPTY / ON ERROR DEFAULT」の値に正しい型修飾が確実に適用されるようになりました。 (Ewan Young) (18)(17)
- money型の最小値(64bit整数最小値)を-1で割ったときの、マシン依存の振る舞いが回避されました。 (Andrey Rachitskiy) (18)(17)(16)(15)(14)
- 全文検索の辞書に対するキャッシュエントリの作成途中でメモリ不足が生じた後にクラッシュする障害が修正されました。 (Tom Lane) (18)(17)(16)(15)(14)
- 誤ったispell/hunspell辞書ファイルに対する処理でメモリ安全性に問題があり、修正されました。 (Andrey Rachitskiy) (18)(17)(16)(15)(14)
- 他セッションの一時テーブルへのアクセスが防止されました。 (Jim Jones, Daniil Davydov, Alexander Korotkov) (18)(17)(16)
- 一時テーブルにアクセスするときの「ERROR: no empty local buffer available」エラーが防止されました。 (Melanie Plageman) (18)
- autovacuumがデータベースを処理する順番が修正されました。 (Rustam Khamidullin) (18)(17)
- VACUUMのXID周回フェールセーフモードで、共有バッファプールを全使用するように動作が復旧されました。 (Melanie Plageman) (18)
- パラレルVACUUMワーカーの処理でのメモリリークが修正されました。 (Baji Shaik) (18)(17)
- 問合せのキャンセルとVACUUM遅延が、GINインデックスのポスティングツリーのクリーンアップ中であっても、すぐに行なわれるようになりました。 (Paul Kim, Alexander Korotkov) (18)(17)(16)(15)(14)
- GiSTおよびSP-GiSTのインデックスに対するIndex Only Scanで、インデックスタプルのデコーディングを誤る可能性があり、修正されました。 (Peter Geoghegan) (18)(17)(16)(15)(14)
- バルク拡張されたテーブルの新たな最終ブロックがフリースペースマップに即座に追加されるようになりました。 (Jingtang Zhang) (18)(17)(16)
- トランザクションのアボート時のリソース解放処理で、メモリの二重解放(クラッシュをひきおこします)、または、エラーの再帰的な無限ループが起きる可能性があり、修正されました。 (Tom Lane) (18)(17)
- PostgreSQLの処理内でディレクトリを作成するとき、同じディレクトリの同時作成を許容するようになりました。 (Andrew Dunstan, Tom Lane) (18)(17)(16)(15)(14)
- JITコンパイルされたタプルデフォームを行うコードが、仮想生成列を正しく考慮するように修正されました。 (David Rowley) (18)
- 依存されている全てのオブジェクトに共有ロックを取得することにより、宙に浮いたオブジェクト依存関係の生成が防止されました。 (Bertrand Drouvot) (18)(17)(16)(15)(14)
- SERIALIZABLE分離モードに対する衝突の検出での競合状態が修正されました。 (Peter Geoghegan) (18)(17)(16)(15)(14)
- バリアイベントの処理で競合状態が修正されました。 (Masahiko Sawada) (18)(17)(16)(15)
- 同じロックグループに属するプロセス集合が同時に終了したときの競合状態が修正されました。 (Vlad Lesin) (18)(17)(16)(15)(14)
- テーブルのビジビリティマップ(VM)でビットをクリアする操作のWAL出力が修正されました。 (Melanie Plageman, Andres Freund) (18)(17)
- WALサマライズ処理でのタイムライン変更時のハングアップが防止されました。 (Robert Haas) (18)(17)
- スタンバイ昇格のときのロジカルデコーディングのタイムライン選択で、競合状態が修正されました。 (Bertrand Drouvot) (18)(17)(16)
- タイムラインを切替するときのwalreceiverの接続文字列の露出が回避されました。 (Chao Li) (18)(17)(16)(15)(14)
- ロジカルレプリケーションで受け取ったタプルの列数が正しいかの検証を、アサートではなく実行時チェックで行うようになりました。 (Varik Matevosyan) (18)(17)(16)(15)(14)
- レプリケーションコマンド内の文字列パラメータへのクォート付加について、実装がクリーンアップされました。 (Tom Lane) (18)(17)(16)(15)(14)
- 空のプリペアドトランザクションのロジカルデコーディングについて修正されました。 (Masahiko Sawada) (18)(17)(16)(15)(14)
- スタンバイ昇格後のUNLOGGEDシーケンスのデータ破損が修正されました。 (Fujii Masao) (18)(17)(16)(15)
- カスケードスタンバイでのWALアーカイブによるリカバリからストリーミングに復帰するときの再接続失敗が、修正されました。 (Marco Nenciarini) (18)(17)(16)(15)(14)
- WALリプレイが一貫性のあるデータベース状態に達する前にホットスタンバイ接続を受け付ける動作が防止されました。 (Nikhil Sontakke) (18)
- スタンバイサーバで、ローカルにpg_database.dathasloginevtのクリアを試みないようになりました。 (Ayush Tiwari) (18)(17)
- 使われなくなったレプリケーションスロットを削除するときの競合状態が回避されました。 (Xuneng Zhou) (18)(17)
- 一時的なレプリケーションスロット(初期化途中の論理レプリケーションスロット)を削除するときの競合状態が回避されました。 (Zhijie Hou) (18)(17)(16)(15)(14)
- ロジカルレプリケーションのテーブル初期同期で、進捗報告が古い内容となっていた問題が修正されました。 (Shinya Kato) (18)(17)(16)(15)(14)
- バックアップに失敗したなら、ベースバックアップの進捗がクリアされるようになりました。 (Chao Li) (18)(17)(16)(15)
- 設定track_functionsが有効であるとき、実行時統計情報(pgstats)のエントリの同時削除のためにPANICが生じる可能性があり、修正されました。 (Sami Imseih, Michael Paquier) (18)(17)(16)(15)
- 対応する共有ハッシュテーブルのエントリに対するメモリ領域取得に失敗した後、壊れた実行時統計情報(pgstats)のローカルエントリをクリーンアップするようになりました。 (Niall Newman) (18)(17)(16)(15)
- 読み込みや書き込みの失敗後に誤ったI/O操作統計が記録されないように、修正されました。 (Bertrand Drouvot) (18)
- PL/Perlで、不正なPostgreSQL::InServer::ARRAYオブジェクトを扱うときのNULLポインタ参照によるクラッシュが回避されるようになりました。 (Xing Guo) (18)(17)(16)(15)(14)
- PL/Pythonで、Pythonのシーケンスオブジェクトとマッピングオブジェクトを扱うときにエラーを正しく検査するようになりました。 (Richard Guo) (18)(17)(16)(15)(14)
- libpqで、pqReadData()の実行中にSSLまたはGSSの復号バッファに残っている未処理バイトを常にすべて取り出すようになりました。 (Jacob Champion) (18)(17)(16)(15)(14)
- libpqのメモリ不足状態の処理が改善されました。 (Anthonin Bonnefoy) (18)
- libpqのトレース機能が、新しい形式のBackendKeyDataメッセージとCancelRequestメッセージを正しく出力するようになりました。 (Anthonin Bonnefoy) (18)
- libpqが30000バイトを超えるParameterDescriptionメッセージを受け付けられるようになりました。 (Ning Sun) (18)(17)(16)(15)(14)
- ecpgコンパイラのNULLポインタ参照によるクラッシュが修正されました。 (Jehan-Guillaume de Rorthais) (18)
- ecpgのGET DESCRIPTOR文とSET DESCRIPTOR文で、記述子ヘッダ項目を複数指定する構文が拒否されるようになりました。 (Masashi Kamura) (18)(17)(16)(15)(14)
- psqlのパイプラインモードにおける遅延エラーの問題が修正されました。 (Michael Paquier) (18)
- psqlの拡張表示(expanded)の整形出力で、行の幅が揃うようになりました。 (Pavel Stehule) (18)(17)(16)(15)(14)
- psqlの特別変数WATCH_INTERVALについて、既定の上限が強制されるようになりました。 (Sven Klemm, Daniel Gustafsson) (18)
- psqlの「\l+」でデータベースサイズを表示する権限検査が修正されました。 (Christoph Berg) (18)(17)(16)(15)(14)
- psqlの「\df」のタブ補完で、プロシージャも候補に含めるようになりました。 (Erik Wienhold) (18)(17)(16)(15)(14)
- pgbenchのスレッド安全性のバグが修正されました。 (Fujii Masao) (18)(17)(16)(15)
- pg_combinebackupで、コピー元ファイルが想定より小さい場合に無限ループが発生することがあり、防止されました。 (Peter Eisentraut) (18)(17)
- pg_createsubscriberで、エラー発生後にパブリッシャ側オブジェクトのクリーンアップが行なわれない場合があり、修正されました。 (Nisha Moond) (18)(17)
- pg_recvlogicalの出力ファイルが、ソースクラスタのグループ読み取り権限に従って作成されるようになりました。 (Fujii Masao) (18)(17)(16)(15)(14)
- pg_restoreの「--statistics」および「--statistics-only」オプションの一貫しない挙動が修正されました。 (Chao Li, Michael Paquier) (18)
- vacuumdbの「--missing-stats-only」が、パーティションテーブルに対する式インデックスを処理対象から除外するようになりました。 (Baji Shaik) (18)
- contrib/amcheckで、btreeインデックスのメタページの「allequalimage」フラグの破損が報告されない問題が修正されました。 (Chao Li) (18)
- contrib/amcheckの GINインデックス検証関数でメモリリークが修正されました。問い合わせが終わるまで未開放メモリが蓄積します。 (Kirill Reshke) (18)
- contrib/amcheckで、ショートヘッダのvarlenaデータムが正しく扱われるように修正されました。 (Andrey Borodin) (18)(17)(16)(15)(14)
- contrib/btree_gistで、float4とfloat8の演算子クラスにおける「NaN」の扱いが修正されました。 (Bill Kim, Tom Lane) (18)(17)(16)(15)(14)
- contrib/btree_gistで、GiSTインデックス構築時のbit型とvarbit型の値のソートが修正されました。 (Tom Lane) (18)
- contrib/btree_gistで、非等価()演算子を使った検索が修正されました。 (Ayush Tiwari) (18)(17)(16)(15)(14)
- contrib/dblinkとcontrib/postgres_fdwで、use_scram_passthroughオプションについて、ユーザマッピングの設定が外部サーバの設定より優先されるよう修正されました。 (Matheus Alcantara) (18)
- contrib/dblinkの外部データラッパのuse_scram_passthroughオプションが拒否されるようになりました。 (Matheus Alcantara) (18)
- contrib/hstore_plperl、contrib/jsonb_plperl、contrib/jsonb_plpythonで保護されていない再帰とループがあり、修正されました。 (Aleksander Alekseev) (18)(17)(16)(15)(14)
- contrib/intarrayでプランナ統計情報のカタログキャッシュエントリの解放漏れが修正されました。 (Man Zeng) (18)(17)(16)(15)(14)
- contrib/ltreeで比較関数における整数オーバーフローが修正されました。 (Ayush Tiwari) (18)(17)(16)(15)(14)
- contrib/pgcryptoで、OSSLCipherオブジェクトの使用中にエラーが発生した後の二重解放によるクラッシュが回避されました。 (Yuelin Wang) (18)(17)
- contrib/pg_prewarmのautoprewarmワーカの範囲外アクセスが修正されました。 (Matheus Alcantara) (18)
- contrib/pg_surgeryのheap_force_kill関数とheap_force_freeze関数で、配列の範囲外書き込みが修正されました。 (Michael Paquier) (18)(17)(16)(15)(14)
- contrib/pg_surgeryで、64K要素を超えるTID配列による無限ループが回避されるようになりました。 (Andrey Rachitskiy) (18)(17)(16)(15)(14)
- contrib/spiのrefint拡張で、check_foreign_key()関数のNULLポインタ参照が回避されました。 (Ayush Tiwari) (18)(17)(16)(15)(14)
- contrib/segで、確実性指示子「~」を持つセグメントの値が正しく出力されるように修正されました。 (Ewan Young) (18)(17)(16)(15)(14)
- contrib/xml2のxpath_nodeset()関数で名前空間ノードを問合せたときのクラッシュが修正されました。 (Andrey Chernyy, Michael Paquier) (18)(17)(16)(15)(14)
- OpenSSL 4を使ったPostgreSQLのビルドに対応しました。 (Daniel Gustafsson) (18)(17)(16)(15)(14)
- タイムゾーンデータファイルをtzdataリリース2026cに更新しました。 (Tom Lane) (18)(17)(16)(15)(14)
- 古いマイナーバージョンが生成したWALのリプレイ時の自己デッドロックが修正されました。 (Andrey Borodin) (16)(15)(14)
- 変数が1つも渡されていない場合でも、未定義のjsonpath変数をエラーとして扱うようになりました。 (Andrey Rachitskiy) (16)(15)(14)
- Visual Studio 2026を使ったPostgreSQLのビルドに対応しました。 (Andrew Dunstan) (16)(15)(14)
これまでは、レプリケーションユーザがロジカルデコーディングむけに任意のライブラリを選ぶことができて(プラグイン名になどフルパス指定も可能)、さまざまな攻撃が可能でした。仕組みを変えずにこれを防げるようにするため、許可された出力プラグインのホワイトリストが導入されました。
PostgreSQL本体同梱のpgoutput(ロジカルレプリケーション用)とtest_decoding(単純なテキスト書き出し用)がデフォルトでoutput_plugin_librariesに含まれます。
加えて、pg_upgrade --checkで、新クラスタのoutput_plugin_librariesが 旧クラスタ(バージョン 17.x 以降)のレプリケーションスロットで使っているプラグインライブラリを許可していない場合、失敗するようになりました。
これまでは、OpenSSLが要求された暗号化方式を(例えば、FIPSモードであるため、あるいは、古いプロバイダがロードされていないために)拒否した場合に、pgcryptoはその失敗を知らせず、プレーンテキストを含む暗号化されないブロックに単にXORを適用していて、その「暗号化」は容易に解読可能でした。これは典型的には非推奨や非FIPSの暗号化アルゴリズム(cipher-algoオプション指定が blowfish/bf, twofish, cast5, 3des などの場合)で発生します。
これからはデフォルトでは、OpenSSLでサポートされない方式でのPGP暗号化がエラーになり、これまでの動作により不適切に暗号化されたメッセージの復号もエラーになります。pgp_pub_decrypt()関数、pgp_sym_decrypt()関数などのオプション引数の新たなオプションignore_cipher_failureに1を指定して実行すると、従来通りの振る舞いに戻ります。
前述の理由で不適切に暗号化されたメッセージを、'ignore-cipher-failure=1'オプションを指定して復号する場合には、OpenSSLの動作がそのメッセージを作成したときと同じでなければなりません。サポートされない暗号化方式が異なっている場合にはうまくいきません。
これまでは「COPY」コマンドが行の読み込みを始める前に(例えば、対象のテーブルが無い、などで)エラーを起こした場合、psqlはこのことを認識できず、続くインラインデータを読んでSQLとして処理しました。これは良くて誤りであり、悪くするとSQLインジェクションを起こします。
これまでも、COPY開始処理が完了してサーバが「PGRES_COPY_IN」を返した後であれば、途中の行読み込みでエラーを起こしても、残りを読み飛ばすように動作していました。
本修正が実運用SQLスクリプトに影響を及ぼすことは無いと考えられますが、テスト用スクリプトでは意図的に「COPY ... FROM STDIN」コマンドが失敗するように作られている場合があります。そのような場合には各コマンドの後に「\.」というデータ区切り行を追加する必要があります。さもないと、読み飛ばす行が多すぎる結果になるかもしれません。
EXECUTEとFETCHは2つのポータルを使います。外側の1つはそのステートメント自身のためで、内側の1つはクエリを代わって実行します。これまで、宣言された2つのポータルの行型を異なるものにできて、これを利用してサーバメモリ暴露や任意コード実行を引き起こせました。
これは容易にバックエンドプロセスのクラッシュができて、任意コード実行をもたらす攻撃も報告されました。
不正な文字エンコーディングのデータを渡すと、変換バッファの終端を過ぎた位置に書き込みが行なわれる可能性がありました。regexp_match()、regexp_matches()、regexp_split_to_table()、regexp_split_to_array()の各関数の動作が修正されました。
不正な文字エンコーディングのデータが入力されることで、騙されて読むべきでない何バイトかを読んで返す可能性がありました。アサートが有効なビルドでは、アサート失敗も発生します。
pg_restore_attribute_stats()はプランナ統計情報のダンプ、リストアで使われる関数です。
pg_restore_attribute_stats()はマルチ範囲型を元となる範囲型と単純に同様に扱っていました。これは境界ヒストグラムについては有効でしたが、他の種類の統計情報に対しては誤っていました。
誤った統計情報のリストアにより、不適切なプラン選択による問合せ実行の遅延や潜在的なプランナ誤動作の可能性が考えられます。
この想定は組み込みの演算子については成り立ちますが、悪意で作られた演算子には通用せず、クラッシュやサーバメモリ暴露を引き起こします。
scalarineqsel()は選択率の見積を返すプランナの内部実装関数の1つです。
ドキュメントに記載されていた上限が、全てのコードパスで必ずしも強制されていませんでした。
本マイナーバージョンアップで、これまで許容されていたデータについて、以下のようなエラーが出るようになる可能性があり、仕様通りであるものの非互換変更ともいえます。
ERROR: lexeme is too long for tsvector ... ERROR: string is too long for tsvector ... ERROR: word is too long to be indexed ... ERROR: tsquery is too large
特に集約関数について、実際の引数の数の上限は「FUNC_MAX_ARGS - 1」ですが、パーサ段階では制限しておらず、後の処理で問題を引き起こしました。潜在的にバッファオーバーランの可能性がありました。
「FUNC_MAX_ARGS」はビルド時指定の定数でデフォルト100です。
拒否するための既存の仕組みはありましたが、不十分であったため、明示的な検査が追加されました。
また、いくつかの集約関数のcombine処理で入力がNULLである場合に正しくSQLとしてのNULLを返すように修正されました。
これまでは拡張統計情報の対象テーブルに、列の型を変えるなどのALTER TABLEコマンドを実行したロールが、拡張統計オブジェクトの所有者になっていましたが、これは不適切な動作と判断されました。
パーサはEXTRACT()のフィールド名としてどのような文字列リテラルも受け付け、検証は実行時まで先送りされます。関数呼び出しを格納して、解析する場合(例えばpg_dumpのとき)、文字列本体が逐語的に吐き戻されて、SQLインジェクションが可能でした。
逆パースはダンプ出力やpsqlでの定義表示で行なわれる処理です。
「CREATE TYPE AS RANGE」、「ALTER TABLE OF」、および、格納される式を作成するコマンド(式を伴うビューやチェック制約の定義など)で、検査が行なわれていませんでした。これらの欠落により、「USAGE」権限を持たないロールでもデータ型に依存するオブジェクトを作成できて、データ型の所有者が後でデータ型を変更できなくなる可能性がありました。
§ § § § § § § § § § § § § § § § § §
ロールのメンバーシップや属性、データベース所有者の変更は、行単位セキュリティポリシーの振る舞いに影響がありますが、これまでは、キャッシュされた古い状態に基づくプランがそのまま使われていました。
これまでサーバは、TLS暗号化接続が確立した後にもGSSAPI暗号化の要求を受け付けていました。これに成功すると、接続はTLS暗号化(SSL)を使っているけれども、pg_hba.confのルールとしてはGSS接続のように見えました。その結果、pg_hba.confでSSLを無効としていても、それを正しく強制できませんでした。
存在しないロールやSCRAMシークレットを持たないロールに対して、SCRAMログインが試みられた場合、PostgreSQLはモックのシークレットを生成して認証のハンドシェイクをとにかく行ない、攻撃者にそのことが分からないようにします。しかしながら、モックが固定のイテレーションカウントで作られていたため、観測可能な応答の差異がありました。
本修正で、モックにもscram_iterations設定パラメータの値を使って、より実際に使われているシークレットに似せるようになりました。
ecpgはbytea型の値は「\x」で始まることを検査せずに想定していました。壊れているか悪意のサーバは2バイトよりも短い文字列を送ってくるかもしれず、そのためにアプリケーションでのメモリ上書きが発生しました。
\restrict と \unrestrict は 17.6、16.10、15.14、14.19バージョンでのCVE-2025-8714の修正で導入されましたが、その中で見落としがありました。悪意のサーバからの応答で出力されたダンプにより、リストアを実行するユーザに意図せぬシェルコマンド実行をさせること(シェルコマンドインジェクション)ができました。
入力引数と出力引数の両方のエントリが存在する可能性があるため、この配列の長さがFUNC_MAX_ARGS(これは入力引数のみに制限するものです)を超えることは十分にあり得ます。仮にそうでは無いとしても、pg_dumpはサーバがpg_dumpと同じFUNC_MAX_ARGSの値でビルドされたと仮定することはできません。オーバーランが発生すると、pg_dump内部でのメモリ破壊を引き起こす可能性がありました。
pg_procシステムテーブルに関数定義が格納されて、protrftypes列にTRANSFORM句による変換のためのデータ型の配列が格納されます。FUNC_MAX_ARGSは実装内部の定数で、通常100です。
通常のオブジェクトとは異なる挙動をするtieされたオブジェクトは、メモリの上書きや、破損した結果配列の生成につながる可能性があり、その結果、後で問題が発生する可能性が高い状況でした。
tieは、配列やハッシュなどの変数に対して操作用のメソッド群を実装したオブジェクトに結びつける Perl の機能です。
これはコードの異なる個所で発生していたCVE-2026-6473と同様の問題で、同じ方法で修正されました。
amcheckはそれらのインデックス式をテーブル所有者の権限で実行するため、呼び出し元がsearch_pathに依存する関数を乗っ取り、テーブル所有者の権限で任意のコードを実行できてしまう恐れがありました。デフォルトでは、amcheck関数の呼び出しはスーパーユーザーにのみ許可されているため、これは脆弱性には当たりません。しかし、もしその権限が他のユーザに付与されていた場合、ドキュメントで示されているよりも大きな危険が生じることになります。
これらの関数に大きなコスト値を渡すと整数オーバーフローが発生し、無意味な結果が生じたり、場合によっては境界外書き込みを引き起こしたりする可能性がありました。
クエリの正規化処理において、正規化後の文字列が必要とするサイズが正確に考慮されていませんでした。
このエラーによりバッファの末尾を超えた読み取りを引き起こし、通常は不適切な分割判断の原因となっており、運が悪ければクラッシュに至る可能性もありました。
このキャッシュの挙動にはいくつかの深刻なバグがありました。特に、check_foreign_key()がカスケードUPDATEクエリに新しいキー値を埋め込んでしまうため、キャッシュされたプランでは、本来使用すべきキー値ではなく、最初に必要とされたキー値が再利用されてしまう問題がありました。最も簡単な解決策は、これを削除することです。
並列ワーカーが処理した行数として初期化されていない値を報告する場合があり、その結果、reltuplesがInfinityやNaNといった不正な値になる可能性がありました。このような値が設定されると、その後のautovacuumやautoanalyze操作において、そのテーブルの処理が必要であると判断されなくなる可能性がありました。そうなると、この状態は自動的には解消されません。
reltuplesを正しい値にリセットするには、手動でANALYZEコマンドを実行するか、別のインデックスを作成する必要があります。 GINインデックスを持つテーブルがある場合は、reltuplesの値が妥当かどうかを確認することをお勧めします。以下のようなクエリが役立ちます。
SELECT DISTINCT t.oid::regclass, t.reltuples FROM pg_class t JOIN pg_index i ON t.oid = i.indrelid JOIN pg_class ic ON i.indexrelid = ic.oid WHERE t.relhasindex AND ic.relam = 2742;
上位のプランノードがAppendの出力をすべて読み取る前にAppendを再スキャンする場合、外部サーバー(例えばpostgres_fdwなど)に対して送信済の未完了リクエストをすべて破棄する必要があります。 サブプランのパラメータが変更された場合や、次回のスキャンでパーティションプルーニングによってサブプランが破棄される場合、この処理が正しく行われていませんでした。 その結果、クエリ結果が不正になったり、無限ループに陥ったり、アサート失敗が発生したりする可能性がありました。
特定のケースにおいて、本来対象とすべきDEFAULTパーティションがスキップされ、その結果、クエリの結果から行が欠落して、誤った問い合わせ結果となる恐れがありました。
以前は、実行時のパーティションプルーニングによって、対象のパーティションテーブルの一部のパーティションをスキャンする必要がないと判断された場合、そのテーブルに外部テーブルのパーティションが含まれていると、クラッシュや誤動作が発生する可能性がありました。
対象行が並行して更新された場合、「READ COMMITTED」分離レベルでは、RETURNING句で返される「OLD」値はすべて、更新後の行の値を反映している必要があります。しかし、トリガーが存在する場合、トリガー自体や最終的な出力行では正しい値が参照されていたにもかかわらず、古い値が返されてしまっていました。結果として、誤った問い合わせ結果が生じる可能性があります。
NULL値を持つタプルは他のどのタプルとも一致することはないため、ハッシュテーブルに挿入されるべきではありません。 これまでのコードでは、最後の結合列以外の列にNULL値が含まれる場合にこの処理が適切に行われていなかったため、NULL値を含む入力が多数あるとハッシュテーブルが著しく肥大化していました。
「(old).colname」や「(old).*」といった式が誤って処理され、実質的に「NEW」への参照に変換されていました。結果として、誤った問い合わせ結果が生じる可能性がありました。
これらのチェックは、配列オペランドが空でないことが既知である場合にのみ成功すべきですが、その点が考慮されておらず、本来適用されるべきではない最適化が適用されてしまう問題がありました。これにより、実際の配列が空であった場合、誤った問い合わせ結果が生じる可能性がありました。
一部の特殊なケースにおいて、外部結合のNULL許容側由来の定数出力値が、本来NULLに置換されるべき場面でNULLに置換されない問題が発生し、誤った問い合わせ結果が生じる可能性がありました。
この修正により、アサート失敗や誤った実行計画の生成(とそれに伴う誤った問い合わせ結果や予期せぬエラー)を招く可能性のあった様々なエッジケースが解消されます。
プランナは、ハッシュベースの実行計画を採用する前に、コンテナの構成要素の型のハッシュ化可能かどうかを検証する必要がありました。一部の箇所でこの手順が漏れていたため、実行時に「ERROR: could not identify a hash function for type ...」という予期せぬエラーが発生していました。
非決定的照合順序でグループ化される列に対するテストは、その同じ照合順序を使用した比較である場合にのみ、安全にプッシュダウンできます。そうでない場合、グループ化によって統合されるはずだった行がフィルタリングされて、誤った問い合わせ結果が生じる可能性がありました。
これまで、このウィンドウ関数は該当しない場合でも単調増加するものとして扱われていました。そのため、誤った問い合わせ結果が生じる可能性がありました。
(報告された誤動作例)
db1=# CREATE TABLE t41 (id int PRIMARY KEY, k int NOT NULL, v int);
db1=# INSERT INTO t41(id, k, v) VALUES
(1, 1, 1), (2, 1, NULL), (3, 1, 1), (4, 2, 1);
db1=# SELECT id, count(v) OVER (
ORDER BY k RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
EXCLUDE CURRENT ROW) AS c FROM t41;
id | c
----+---
1 | 1
2 | 2
3 | 1
4 | 2
(4 rows)
db1=# SELECT * FROM (
SELECT id, count(v) OVER (
ORDER BY k RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
EXCLUDE CURRENT ROW) AS c FROM t41) s WHERE c < 2;
id | c
----+---
1 | 1
(1 row)
→ 正しくは id=3 の行も出力されないといけない
"char"型は、一般的に使われるchar(n)型とは別の、主として内部的なシステムカタログで使用されるものです。
ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSIONは、格納生成列を基本列に変換する構文です。複数階層の子パーティション/子テーブルを持つパーティションテーブルや継承ツリーの親テーブルに対して実行すると、「ERROR: ALTER TABLE / DROP EXPRESSION must be applied to child tables too」というエラーが発生していました。
この誤りにより、排他制約を持つパーティションテーブルのダンプ/リストアが正常に動作しなくなっていました。
リストア時に以下のようなエラーが発生します。
ERROR: cannot attach index "..." as a partition of index "..." DETAIL: The index definitions do not match.
本来、パーティションテーブルのNOT NULL制約は、すべてのパーティションに継承される仕様であるため、NO INHERITを指定することはできません。これまでは、この仕様は制約を新規作成する際には正しく適用されていましたが、「ALTER TABLE ... ALTER CONSTRAINT」では適用されておらず、NO NULL制約の有無がパーティションごとに異なるようにできました。
「_RETURN」という名前は、ビューの「ON SELECT」ルール用に予約されています。これまでは「ON SELECT」以外のルールをALTER RULEで「_RETURN」に名前変更できてしまい、その後の処理で問題を引き起こしていました。
具体的には、ダンプ/リストアで「ERROR: non-view rule for "..." must not be named "_RETURN"」というエラーを起こすことが報告されました。
この不具合により、トランザクションが終了するまで、ロールメンバーシップ(pg_auth_membersシステムテーブルの対応するエントリであらわされる暗黙的なオブジェクト)へのロックが保持され続けていました。その結果、並行するDDL実行で警告メッセージが出ることがありました。
実行プランの構造によっては、「ERROR: invalid JsonConstructorExpr underlying node type」というエラーが発生していました。
REINDEX CONCURRENTLYの実行中に一時的に作成されるインデックスのコピーが、誤って即時一意性制約として扱われていました。そのため、実際には制約違反ではない場合でも、制約違反が発生したと誤って報告することがありました。
非決定論的照合順序において、LIKEがエスケープされたバックスラッシュ(\\)を誤って処理し、実質的にバックスラッシュが存在しないものとして扱っていました。
また、通常の文字の前にバックスラッシュが付いている場合も誤った処理をしていました。この場合、バックスラッシュは実質的に無視されるべきですが、実際には後続の通常の文字を完全一致として扱ってしまい、非決定論的照合順序にマッチするかを判断していませんでした。
非決定論的な照合順序におけるLIKEのリファクタリングによって、LIKE句や正規表現の完全一致パターンを、等価比較のインデックス条件に変換する最適化が誤って壊れていました。これはインデックスの照合順序と式の照合順序が一致しない場合に発生していました。この影響で、psql の「\d tablename」コマンドが大幅に遅くなっていました。
大文字・小文字の変換によって文字列のバイト長が変化する場合に、マッチング処理が誤動作していました。月名、曜日名が認識されずに予期せぬエラーが発生する可能性が考えられます。
文字列の直前が大文字小文字を区別しない文字だけで構成されている場合、そのシグマを語末形のシグマとはみなさないようにしました。
この文字は有効なT音節として扱われていましたが、実際にはT音節ではないため、正規化処理中にこの文字が消えてしまっていました。
小文字への変換によって語彙素のバイト長が増加した場合、出力時に元のバイト長に誤って切り捨てられていました。
FunctionCallInvoke()に渡される2番目のisnull引数が初期化されていませんでした。既存の組み込み拡張ハッシュサポート関数では、この値を参照しないため問題はありません。しかし、拡張機能が提供するハッシュ関数が「PG_ARGISNULL(1)」を調べる場合、その影響を受ける可能性がありました。
具体的には、表示可能なASCII文字ではない重み文字については、charout()と同様に8進数形式("\nnn")で報告します。これにより、無効なエンコーディングを含むエラーメッセージが生成されるのを防ぎます。
v7 UUIDで表現可能な範囲を超えたタイムスタンプになるシフト値は「ERROR: timestamp out of range for UUID version 7」というエラーを出すようになります。有効なタイムスタンプ範囲は、1970-01-01 00:00から10889年くらいまでです。これまでは壊れたUUID値が作られていました。
予期せぬ「ERROR: could not copy node」エラーが出ていたものが修正されました。
サイレントモード(json_path_*関数のsilent引数がtrue)では、エラーを抑止すべきですが、そのようになっていませんでした。
PostgreSQL本体コードには該当するデータ型はありませんが、一部の拡張のデータ型で問題を引き起こす可能性がありました。
例えば、対象numeric型列の宣言された精度とスケールがデフォルト値に適用されませんでした。
(誤動作例)
db1=# SELECT JSON_VALUE(jsonb '{"b":"1234.5"}', '$.a'
RETURNING numeric(4,1) DEFAULT 99999.9 ON EMPTY);
json_value
------------
99999.9
(1 row)
(以下エラーが出るのが正しい動作)
ERROR: numeric field overflow
x86_64アーキテクチャでエラーになるものが、aarch64アーキテクチャではエラーになりませんでした。オーバーフローを起こした場合には必ず「ERROR: money out of range」が出るようになりました。
基本的にそのようなアクセスは禁止されていますが、一部のコードパスで防止しきれておらず、干渉されたセッションで誤った問合せ結果が生じるおそれがありました。
本修正でストリーミング読み取りの仕組みが使用可能なローカルバッファの数が制限されました。これまでは、effective_io_concurrency設定が大きな値の場合に単一のストリームで全バッファを利用可能であったため、本エラーが発生しました。
最高スコアから最低スコアに向かう順で処理されるべきところで、意図せず逆順になっていました。
通常のVACUUMは、他の処理に大きな影響を与えないように、共有バッファを少しだけ使うように制限されています。しかしながら、フェールセーフモードではできるだけ早くトランザクションIDを回収する必要があるので、この制限は放棄されることになっていました。この振る舞いがv18のリファクタリングで壊れていて、復旧されました。
パラレルワーカーからの報告過程で報告ごとに1kB程度のリークがあり、これはワーカープロセスが生きている間は蓄積されていきました。
よくある値に対するポスティングツリーは大きくなることがあり、ここに割り込みの検査が欠けていたため、処理が長く継続してしまいました。
この障害で壊れたデータが出力されて、誤った問い合わせ結果や予期せぬエラーが発生する可能性がありました。本体コードで影響があるのは、GiSTの演算子クラスrange_opsのみで、その範囲列が最初のインデックス列でない場合にのみ、誤動作が発生します。
(誤動作例)
db1=# CREATE TABLE t75 (a inet, r numrange);
db1=# INSERT INTO t75 VALUES
('::1', numrange(repeat('1', 100)::numeric, repeat('2', 200)::numeric)));
db1=# CREATE INDEX ON t75 USING gist (a inet_ops, r range_ops);
db1=# VACUUM ANALYZE t75;
db1=# SET enable_seqscan TO off;
db1=# SELECT lower(r) = repeat('1', 100)::numeric,
upper(r) = repeat('2', 200)::numeric FROM t75;
ERROR: type with OID 860 does not exist
off-by-one(1つ足りない)誤りで、複数ブロックが追加されたときの最後のブロックがフリースペースマップに登録されませんでした。VACUUMによってやがては正しく登録されますが、それまでの間、最終ブロックが使われませんでした。
巨大な入力値を伴うSQLがエラーになって、トランザクションアボートが行なわれたケースで問題が報告されました。
他プロセスが同じディレクトリを作っているのであれば、ディレクトリ作成に成功した扱いとすることで、これまで同時実行で発生する可能性のあった「ERROR: could not create directory "...": File exists」といったエラーを回避できます。
NOT NULL制約のある仮想生成列を含むテーブルへの問合せで、誤った問い合わせ結果が生じる例が報告されました。
共有ロックは依存されているオブジェクトの削除と衝突しますので、これまであった競合状態を排除することができます。
例えば、これまでは、空スキーマの削除とスキーマ内へのオブジェクト作成の同時実行が両方成功して、無効なオブジェクト定義が残ることがありましたが、これからはどちらかのトランザクションが失敗します。
初期の空のbtreeインデックスを検査するときに衝突が見過ごされる可能性があり、競合しているトランザクションのコミットを許してしまっていました。
この誤りにより、プロセスがハングアップする可能性がありました。典型的には、その際に以下ログメッセージが出力されます。待機イベントとしてはIPC型のProcSignalBarrierの待機となります。
LOG: still waiting for backend with PID %d to accept ProcSignalBarrier
近年追加されたオンラインWALレベル変更などの機能によって、この問題がより目立つようになっています。
この誤りは「PANIC: latch already owned by PID ..」によるサービスのPANIC終了を引き起こす可能性があります。PostgreSQL本体の通常のパラレル問合せでは、リーダープロセスがワーカープロセスの終了を待たずに終了することが無いため、この問題は起きませんが、何らかの拡張で該当する可能性がありました。
このようなVM変更がWALサマライズ処理で見落とされていて、誤ったインクリメンタルバックアップをもたらす可能性がありました。また、このようなVMページの必要時のフルページイメージWAL出力も行なわれておらず、壊れたページ書き込みが修正されないままとなる可能性がありました。これは後にIndex Only Scanでの誤った問い合わせ結果が生じるなどの、誤動作を引き起こすおそれがあります。
既存のバックアップやアーカイブWALに潜在的にデータ破損が含まれていることに留意してください。
スタンバイサーバで、以下のログメッセージがwalsummarizerプロセスから継続的に出力される動作が報告されました。
ERROR: could not read WAL from timeline .. at ...: invalid record length ...
スタンバイ側で実行中のロジカルデコーディングが「ERROR: requested WAL segment has already been removed」で失敗する可能性がありました。再試行すれば成功するため恒久的な問題はありませんが、可用性としては有害でした。
pg_stat_wal_receiverビューは機微なデータを除いてサニタイズされた接続文字列を見せるべきです。しかし、タイムライン切替に際して既存のwalreceiverプロセスを再利用するときに、一時的に完全な接続文字列を見せてしまっていました。
悪意の、または、壊れたパブリッシャは一貫性のない列数を送出するかもしれません。これによる深刻な悪影響をおよぼすシナリオは見つからなかったものの、より注意を払うべきと判断されました。
レプリケーションコマンドを生成する様々な個所で、コマンドに挿入されるレプリケーションスロット名や他のパラメータのクォート付加について、十分な注意が払われていませんでした。そのため、レプリケーションコマンドで予期せぬエラーが発生するおそれがありました。
原理的には作りこまれたレプリケーションスロット名でSQLインジェクションも可能でした。ただし、ほとんどの場合、元からSQL実行が可能な管理者が行う操作であるため、実用的な害はないと考えられます。
デコード可能な変更を起こさないプリペアドトランザクションは、先立つ「PREPARE」無しに、「COMMIT PREPARED」や「ROLLBACK PREPARED」を出力プラグインに送出していました。組み込みのサブスクライバでは、これはレプリケーションを壊します。他のプラグインでも同様に問題となると考えられます。
これまでは、プライマリで作られてスタンバイにレプリケートされたUNLOGGEDシーケンスに、スタンバイ昇格後にアクセスすると、「ERROR: bad magic number in sequence」などのエラーや、アサート失敗が発生する可能性がありました。
このとき「ERROR: requested starting point ... is ahead of the WAL flush position」が発生する可能性がありました。
スタンバイで実行が試みられていましたが、これは機能しておらず、また、プライマリでの変化がすぐに反映されて上書きされるので不要な動作でした。
loginのイベントトリガを削除した後にスタンバイに接続したときに、「FATAL: cannot acquire lock mode AccessExclusiveLock on database objects while recovery is in progress」が出て接続できない動作が報告されました。
削除直後のスロットの共有メモリエントリを他セッションが再利用した場合、誤ったロック解放と誤ったログメッセージ(異なるスロット名やデータベースOIDが使われる)が生じる可能性がありました。
これまでの実装では、スロットを解放した後にスロットの共有メモリエントリにいくらか追加的な更新を実行していました。これは他セッションが直ちに再利用するかもしれないため、安全ではありません。本修正で、一時スロットには、この更新を行なわないようになりました。
これまでは、サブスクライバのpg_stat_progress_copyビューは、データコピーが終わった後でも、初期COPY操作をアクティブとして表示していました。同期がパブリッシャに追いつくまで、古いエントリが表示されたままでした。
これまで、pg_stat_progress_basebackupビューは、レプリケーションクライアントが切断するまで、古い進捗情報を表示し続けていました。標準付属のpg_basebackupであれば、失敗した後に即座に切断しますが、他のバックアップを取得するクライアントはそうであるとは限りません。
「PANIC: cannot abort transaction .., it was already committed」が出るケースが報告されました。
§ § § § §これを行なっていなかったため、次にローカルエントリが使われたときに、NULLポインタ参照によるクラッシュが発生しました。
各種のWAL読み書きに処理に失敗したときにエラーを意味する負の値がそのまま統計値のカウントに使われていて、pg_stat_ioビューなどで参照されるWALのI/O統計に誤った値が混入する可能性がありました。
PostgreSQL::InServer::ARRAYはPL/Perl関数に引数でPostgreSQLの配列を渡すときに使われるperlのオブジェクト型です。PL/Perl関数からPostgreSQLの配列を返すときにも使用できます。検査が不足していて、引数に由来せず適切な内部構造を持たないPostgreSQL::InServer::ARRAYオブジェクトを返すとクラッシュを引き起こせました。
(クラッシュ発生例)
=# CREATE FUNCTION f102() RETURNS integer[] AS $$
return bless {}, "PostgreSQL::InServer::ARRAY"; $$ LANGUAGE plperl;
=# SELECT f102();
server closed the connection unexpectedly
hstore_plpython拡張やjsonb_plpython拡張を使って、PL/Python関数の戻り値をhsotre型やjsonb型に変換している場合に該当する問題です。これまでは、壊れたオブジェクトやハンドルされない例外によって、NULLポインタ参照によるクラッシュが発生する可能性がありました。
例外的なケースですが、大きなメッセージのサーバからの届き方によっては、バッファがいっぱいになることでlibpqがソケット到着を誤って待ち続けて、APIを呼び出すクライアントアプリケーションがハングアップしてしまう可能性がありました。
pqReadData()はサーバ側からデータを読むlibpqの内部実装関数です。
§ § § § § § § § § § § § § § § § § § § § § § § §
COPYデータ読み込みや関数呼び出しの途中に、非同期メッセージ処理でメモリ不足になった場合にも、直ちにエラーを出すようになりました。これまでは、セッション切断された状態で処理が継続されていて、エラー発生が遅れたり、不適切なエラーが出る可能性がありました。
これらのプロトコルメッセージは固定長から可変長に仕様変更されましたが、トレース機能では固定長を想定したままとなっていたため、「mismatched message length」という警告が出力されていました。
libpqは受信メッセージの妥当性検査として、「長くなりうるメッセージ型」以外について長すぎるメッセージを弾きます。ParameterDescriptionは「長くなりうるメッセージ型」として扱われていなかったため、メッセージ長が30000バイトを超えるとエラーになっていました。この制限により、7498個を超えるパラメータを持つプリペアドステートメントに対するPQdescribePrepared()が失敗していました。この数のパラメータはまれな用法ですが仕様の範囲内です。
構造体の内側に入れ子になった共用体を含むDECLAREセクションをもつ.pgcコードを変換しようとすると、ecpgコマンド実行がクラッシュしました。
(ecpgコマンドがクラッシュするコード例)
EXEC SQL BEGIN DECLARE SECTION;
struct s1
{
char STR1[10];
union u1
{
int NUM1;
int NUM2;
} U1;
} S1;
EXEC SQL END DECLARE SECTION;
これまでも文法上はこの構文が許されていましたが、実装は実際には複数のヘッダ項目に対応できておらず、指定すると壊れたCコードが生成されていました。
本修正で構文解析処理でもドキュメント上でもヘッダ項目は1つだけに変更されました。これは非互換性を含む変更です。
Syncメッセージへの応答としてサーバがエラーを報告する場面(遅延制約の違反など)で、psqlがハングアップしたり、アサート失敗したりする可能性がありました。
テーブルのデータ行がレコードヘッダ行より狭い場合、データ行の幅がレコードヘッダ行に合わせられず、次のように桁のずれた出力になっていました。
(ずれた出力の例) +-[ RECORD 1 ]-+ | a | 10 | | b | 20 | +---+----+ (修正後の出力例) +-[ RECORD 1 ]-+ | a | 10 | | b | 20 | +---+----------+
大きすぎる値(1000000超)を設定しようとすると、psqlはエラーを報告するものの、その値を適用してしまっていました。修正後は、上限を超える値は拒否され、変数の値は変更されません。
サーバ側のpg_database_size()は、pg_read_all_statsロールの権限を持つ利用者に対して、対象データベースへのCONNECT権限がなくてもすべてのデータベースのサイズの参照を許します。しかしpsqlはこの仕組みを考慮せず、CONNECT権限を持つ利用者以外に対してはこの関数を呼び出していませんでした。
修正後は、「\l+」の権限検査にpg_read_all_statsロールの権限(USAGE)の確認が加わり、pg_database_size()の権限規則と一致するようになりました。
「\df」コマンド自体はプロシージャも表示対象に含めるよう拡張されていましたが、タブ補完の候補は関数だけを表示し続けていました。
pgbenchを複数スレッドで実行し、かつ「--verbose-errors」オプションを指定した場合、異なるスレッドが同じバッファを使ってエラーメッセージを組み立てようとし、ログ出力が壊れる可能性がありました。
「--copy-file-range」を指定して合成フルバックアップを再構築する過程で、ファイルが0バイトしかコピーできなかった場合をエラーとしていなかったため、試行が繰り返されてしまっていました。
pg_createsubscriberは、論理レプリケーションオブジェクトを作成した後にエラーを起こした場合、パブリッシャ上に作成したパブリケーションとレプリケーションスロットを削除する必要があります。一部のエラーケースでは削除が行われず、pg_createsubscriberの再実行のために手動での削除が必要でした。
pg_recvlogicalはこの挙動についてドキュメントに記載されていたにもかかわらず、実際にはソースクラスタのグループ読み取り権限を反映した書き出しが行なわれず、常にファイル所有者の読み書きのみを許すモードが使われていました。
「--schema」「--table」などの選択的リストアオプションと組み合わせた場合に意図通りの要素がリストアされませんでした。pg_dumpで対象選択オプションを組み合わせた場合と同様に動作するように修正されました。
(誤動作例) $ psql -d db1 <<EOS CREATE TABLE t119 AS SELECT g id, g % 5 n FROM generate_series(1, 20) g; CREATE STATISTICS s119 ON id, n FROM t119; ANALYZE; EOS $ pg_dump --statistics -Fc db1 -f db1.dmp (プランナ統計情報を含むダンプファイルを作る) $ pg_restore --table t119 --statistics-only -f - db1.dmp (→「t119テーブルの統計情報のみをリストア」の意図だが、リストア内容が空になる) $ pg_restore --statistics --table t119 -f - db1.dmp (→「統計情報を含めてt119テーブルをリストア」の意図だが、拡張統計情報が欠損する)
これまで、本オプションのvacuumdb実行では、パーティションテーブルに式インデックスがあると、常にそのパーティションテーブルにANALYZEを実行しようとしていました。しかし、統計情報は子パーティションのインデックスに作成されても、パーティションテーブルのインデックスには作成されないため、意味がありませんでした。
btreeインデックスを検査する関数は、これまでインデックスキー列のいずれかにinterval_ops演算子クラスを含む場合のみ正しく動作していて、そうでないインデックスでこの破損が見逃される可能性がありました。
大きなGINインデックスの検証でメモリ使用量が増大するおそれがありました。
この誤りで、btreeインデックス検証で無駄な処理が生じる可能性がありますが、それ以上の悪影響は無いと考えられます。
varlenaデータムとはPostgreSQL実装内で使われる長さとデータ本体からなるデータ構造です。ショートヘッダは長さをあらわすのに1バイトだけ使う形式です。
各種の比較関数と、GiSTのpenalty関数、distance関数が「NaN」を考慮しておらず、「NaN」を渡されたときに誤った結果を返していました。
本修正の適用後、float列のbtree_gistインデックスに「NaN」のエントリが含まれる可能性がある場合は、それらのインデックスの再構築を推奨します。
これまでbit型の値がbytea型であるかのようにソートされていました。これは明白な誤動作を引き起こすことはありませんでしたが、型本来のソート順に一致しない並びで構築されるため、非効率なインデックスになりました。
本修正の適用後、bit列上のbtree_gistインデックスの再構築を推奨します。
可変長データ型の場合、非リーフインデックスページを走査するコードが誤った比較関数を適用していました。これは誤った問い合わせ結果、および場合によってはクラッシュにつながる可能性がありました。
これまでは外部サーバ側の設定が優先されていましたが、これは他の外部テーブルオプションの挙動と一貫していませんでした。他の接続オプション(sslcertやsslkeyなど)と同様に、外部サーバのオプションは共通のデフォルト値を提供し、ユーザマッピングのオプションがそれを上書きする扱いに統一されました。
これは非互換性を含む変更と言えます。
このオプションは外部サーバとユーザマッピングに対してのみ意味を持ちますが、dblinkは外部データラッパ(dblink_fdw)レベルでもこのオプションを受け付けていました(そして受け付けた設定を無視していました)。
深くネストしたjsonb値を扱うときのスタックオーバーフロー(によるクラッシュ)が防止されました。また、Perlのオブジェクト参照の循環チェーンをたどるときに生じる無限ループが割り込み可能になりました。
この解放漏れにより、「WARNING: resource was not closed: cache pg_statistic ..」のような警告が発生していました。
約14,653個を超えるラベルを含むltree値は、オーバーフローによって誤った比較結果を返していました。btreeインデックスにそのような値が含まれている場合、破損している可能性があるため、本修正の適用後に再構築することを推奨します。
このコードは、配列の末尾の1つ先から値を取り出そうとしており、セグメンテーション違反によるクラッシュを引き起こす可能性がありました。
オフセット番号がMaxHeapTuplesPerPage(ページあたりの最大タプル数、291など)に等しいTIDを変更しようとすると、確保された配列の末尾の1バイト先に書き込み、サーバをクラッシュさせる可能性がありました。
ON UPDATE CASCADEの場合、参照列の新しいキー値がNULLであると、クラッシュが発生していました。これはCVE-2026-6637の修正の見落しですが、その前からあったコードも正しいものではありませんでした。
seg型の出力関数seg_out()はセグメントの上限に付いた「~」を出力していませんでした。さらに悪いことに、下限に「~」があり上限に指示子がない場合、上限がまったく出力されませんでした。なお、文字列としての出力が不正であるだけで、演算結果に影響はありません。
(誤動作例:2番目と3番目が誤動作) db1=# SELECT '~1 .. ~5'::seg, '1 .. ~5'::seg, '~1 .. 5'::seg; seg | seg | seg ----------+--------+-------- ~1 .. ~5 | 1 .. 5 | ~1 .. (1 row)
以下のように、query引数に「//namespace::」を指定した場合にクラッシュするケースが報告されました。
db1=# SELECT xpath_nodeset(
'<root xmlns:foo="http://example.com/foo"><child/></root>',
'//namespace::*');
アルバータ州(America/Edmonton)は、2026年11月から年間を通したUTC-06(実質的に、恒久的なサマータイム)になります。このリリースでは、それ以降のタイムゾーン省略形は「CST」と仮定しています。この仮定は将来変更される可能性が高いのですが、新しい省略形に何が使われるかは明らかになっていません。
モロッコ(Africa/Casablanca)は、2026-09-20に、サマータイムの切り替えなしの恒久的なUTC+00に移行します。
この不具合は前回のマイナーリリース(16.14、15.18、14.23)で導入されました。より古いマイナーバージョンのプライマリに追従するスタンバイサーバで、startupプロセスがハングアップしてレプリケーションが先に進まなくなりました。
共有行ロックで使われるマルチトランザクションに関するWALレコードのリプレイで問題が発生しました。
jsonbの「@?」演算子と「@@」演算子がjsonpath式の中で使う変数を渡せない、という場合のコードパスでは、未知のjsonpath変数が、本来の期待であるエラーの発生ではなく、JSONのnullとして誤って扱われていました。期待される動作でないことに加えて、この誤りは無制限のメモリ消費を引き起こす可能性がありました。
(誤動作例)
db1=# select '{"A":1}'::jsonb @@ '$"no_such_var" == 1';
?column?
----------
f
(1 row)
db1=# SELECT '{"A":1}'::jsonb @? '$"no_such_var"';
?column?
----------
t
(1 row)
(修正後は以下のエラーが出る)
ERROR: could not find jsonpath variable "no_such_var"