[pgpool-general-jp: 1146] 拡張問い合わせプロトコルでセグメンテーションフォルト

Naoya Anzai anzai-naoya @ mxu.nes.nec.co.jp
2013年 3月 14日 (木) 19:13:42 JST


安西と申します。

pgpool-II 3.1.6にて、レプリケーションモードで拡張問い合わせ
プロトコルを使用したトランザクションを実行中に、子プロセスが
SIGSEGVで落ちる現象が発生しました。

添付のsegv.sql内に記載されているクエリを実行することで、
発生します。(INSERT,SELECTをより多く繰り返さないと発生しない
可能性もあります。)

調査したところ、Parse処理中のnow()の書き換え処理を行う部分で、
不正な処理と思われる箇所を発見いたしました。

pool_proto_modules.c:L774

---
rewrite_query = rewrite_timestamp(backend, node, rewrite_to_params, 
msg);
if (rewrite_query != NULL)
{
  int alloc_len = len - strlen(stmt) + strlen(rewrite_query);
★contents = palloc(alloc_len);
  strcpy(contents, name);

(略)

●msg->contents = contents;
---

msg->contentsには元々pool_create_sent_messageでセッション
コンテキストで管理しているメモリを割り当てています。
★印のpallocはクエリコンテキストのメモリを割り当てており、
●印の箇所でセッションコンテキストの管理する領域にクエリ
コンテキストのメモリが格納されます。

msg->contentsのメモリチャンクはクエリ処理終了後にセッション
コンテキストのメモリプールに戻され、再利用されるかと思います。
また、クエリコンテキストのメモリチャンクはクエリ処理終了後に
ブロックごと削除(free)されるかと思います。

そのため●の影響によって、セッションコンテキストのメモリ
プールに戻されたメモリチャンクがクエリコンテキストの
削除によってfreeされ、そのメモリチャンクをセッション
コンテキストで再利用するタイミングで問題が発生するようです。

本障害が発生する条件は最低でも以下の4つがあります。

・レプリケーションモード
・拡張問い合わせプロトコル
・更新系クエリでnow()等を含むクエリを発行
・同一セッションで複数のクエリを発行

本現象は3.0.5 , 3.1.4 , 3.2.3でも発生することを確認しています。

修正パッチを作成してみましたので、ご確認いただければと思います。


以上、よろしくお願い致します。

-----------------------------------------------------------
NECソフト株式会社
PFシステム事業部  テーマソフトウェアG
安西 直也

外線:(03)5534-2353  内線:8-57-40364
E-mail:anzai-naoya @ mxu.nes.nec.co.jp
-----------------------------------------------------------
-------------- next part --------------
CREATE TABLE segv (c1 int, c2 date, c3 time, c4 timestamp, c5 timestamptz);
INSERT INTO segv VALUES (1, now(), now(), now(), now())                                                                                                                                                                                                                                                                                                                                                                  ;
SELECT pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv');
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: pool_proto_modules.patch
型:         application/octet-stream
サイズ:     601 バイト
説明:       無し
URL:        <http://www.sraoss.jp/pipermail/pgpool-general-jp/attachments/20130314/701af1e7/attachment-0001.obj>


pgpool-general-jp メーリングリストの案内