[pgpool-committers: 9934] pgpool: Fix segfault in a child process.

Tatsuo Ishii ishii at sraoss.co.jp
Wed Jun 12 19:48:31 JST 2024


Fix segfault in a child process.

It is reported that pgpool child segfaulted [1].

[snip]

In the down thread it is reported that despite VALID_BACKEND(i)
returns true, backend->slots[i] is NULL, which should have been filled
by new_connection().

It seems there's a race condition. In new_connection(), there's a code
fragment:
                /*
                 * Make sure that the global backend status in the shared memory
                 * agrees the local status checked by VALID_BACKEND. It is possible
                 * that the local status is up, while the global status has been
                 * changed to down by failover.
                 */
A-->            if (BACKEND_INFO(i).backend_status != CON_UP &&
                        BACKEND_INFO(i).backend_status != CON_CONNECT_WAIT)
                {
                        ereport(DEBUG1,
                                        (errmsg("creating new connection to backend"),
                                         errdetail("skipping backend slot %d because global backend_status = %d",
                                                           i, BACKEND_INFO(i).backend_status)));

                        /* sync local status with global status */
B-->                    *(my_backend_status[i]) = BACKEND_INFO(i).backend_status;
                        continue;
                }

It is possible that at A backend_status in the shared memory is down
but by the time it reaches B the status has been changed to up. And
new_connection() skipped to create a backend connection. This seems to
explain why the connection slot is NULL while VALID_BACKEND returns
true. To prevent the race condtion, backend_status in shared memory is
copied to a local variable and evaluate it.  Also the VALID_BACKEND
just before:

        pool_set_db_node_id(CONNECTION(backend, i), i);

is changed to:
                        if (VALID_BACKEND(i) && CONNECTION_SLOT(backend, i))

so that it prevents crash just in case.

[1] [pgpool-general: 9104] Another segmentation fault

Branch
------
V4_2_STABLE

Details
-------
https://git.postgresql.org/gitweb?p=pgpool2.git;a=commitdiff;h=622ff0e47877c1b3c8d5b65903197b3dd8633964

Modified Files
--------------
src/protocol/child.c                | 3 +--
src/protocol/pool_connection_pool.c | 7 ++++---
2 files changed, 5 insertions(+), 5 deletions(-)



More information about the pgpool-committers mailing list