Fix memory leak in extended query + query cache enabled.
authorTatsuo Ishii <ishii@sraoss.co.jp>
Thu, 1 Nov 2018 00:22:46 +0000 (09:22 +0900)
committerTatsuo Ishii <ishii@sraoss.co.jp>
Thu, 1 Nov 2018 00:37:00 +0000 (09:37 +0900)
If a bind message is sent again to an existing prepared statement, it
is possible that the previously allocated bind parameter string
remains and newly allocated bind parameter string's pointer is set to
there, which leads to a memory leak.

Note that if a statement is parsed again in usual way, the parameter
string will be freed along with the old query context. So the leak
does not happen.

I suspect the use case for the memory leak (bind, execute is repeated
against a same prepared statement) is actually rare in the
field. Probably that's why the problem has not been reported until
today although the leak had existed since day 0.

The leak case can be easily reproduced by "pgbench -M prepared" by the
way.

src/protocol/pool_proto_modules.c

index 55991992bf5ac570a40ab78c469175c5243092f6..9cec160d0d1c8513b7ce6adaec52cd85fdb88605 100644 (file)
@@ -681,6 +681,16 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
                                len += hexlen;
                        }
 
+                       /*
+                        * If bind message is sent again to an existing prepared statement,
+                        * it is possible that query_w_hex remains. Before setting newly
+                        * allocated query_w_hex's pointer to the query context, free the
+                        * previously allocated memory.
+                        */
+                       if (query_context->query_w_hex)
+                       {
+                               pfree(query_context->query_w_hex);
+                       }
                        query_context->query_w_hex = search_query;
 
                        /*