[PATCH] Fix hostaddr crash during non-blocking cancellation

Started by Jacob Championover 1 year ago4 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

won't retrysuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t51538
psql -h localhost -U postgres

Built from patchset v1 (message #1), July 27, 2026 at 09:13 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t51538_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t51538_1 && git checkout t51538_1

Patchset v1 (message #1) is on t51538_1

Jump to latest
#1Jacob Champion
jacob.champion@enterprisedb.com

Hi all,

A connection with only a hostaddr (no host) can't be cancelled via
PQcreateCancel(), because we'll crash in emitHostIdentityInfo(). The
problem is that the synthetic connhost entry we've created for
cancellation has an incorrect type field, which causes the following
code to make bad decisions if connhost[0].host is NULL:

emitHostIdentifyInfo(...)
{
...
if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
displayed_host = conn->connhost[conn->whichhost].hostaddr;
else
displayed_host = conn->connhost[conn->whichhost].host;
...
if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS &&
host_addr[0] &&
strcmp(displayed_host, host_addr) != 0) <- crashes here

I think the solution is just to copy over the correct type, as done in
the attached 0001.

Putting in a regression test requires us to once again answer the
question of "where do we test TCP-only features". I'd like to have a
PG_TEST_EXTRA entry for these, so 0002 adds a `tcp` group. That's
going to need more debate, and 002_tcp.pl is very quick-and-dirty, but
I also _really_ want to stop throwing tests away just because we don't
have a nice place to put them... [1]/messages/by-id/flat/CAOYmi+kx8eOmKj01dV4vSBeq9pvqR8dt6rGw+B_pBOE2_GOj+g@mail.gmail.com

So: if 0001 looks good, I propose that I backpatch it after beta1, but
hold onto 0002 until REL_18_STABLE is split off. Then we can figure
out the "test TCP" semantics for the full 19 cycle, and maybe
eventually backpatch tests once we're happy with how they work.

WDYT?

--Jacob

[1]: /messages/by-id/flat/CAOYmi+kx8eOmKj01dV4vSBeq9pvqR8dt6rGw+B_pBOE2_GOj+g@mail.gmail.com

Attachments:

t51538_1
v1-0001-Fix-connhost-type-during-non-blocking-cancellatio.patchapplication/octet-stream; name=v1-0001-Fix-connhost-type-during-non-blocking-cancellatio.patchDownload+2-1
v1-0002-WIP-add-TCP-tests.patchapplication/octet-stream; name=v1-0002-WIP-add-TCP-tests.patchDownload+47-2
#2Greg Sabino Mullane
greg@turnstep.com
In reply to: Jacob Champion (#1)
Re: [PATCH] Fix hostaddr crash during non-blocking cancellation

01 looks sensible to me.

I like 02 as well. Only quibble would be the name (tcp) as it doesn't
really describe a class of things to be tested like the other things in
PG_TEST_EXTRA. Something indicating a lack of socket? Just more verbose
somehow? "tcp_only" perhaps?

Cheers,
Greg

--
Crunchy Data - https://www.crunchydata.com
Enterprise Postgres Software Products & Tech Support

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jacob Champion (#1)
Re: [PATCH] Fix hostaddr crash during non-blocking cancellation

Jacob Champion <jacob.champion@enterprisedb.com> writes:

A connection with only a hostaddr (no host) can't be cancelled via
PQcreateCancel(), because we'll crash in emitHostIdentityInfo(). The
problem is that the synthetic connhost entry we've created for
cancellation has an incorrect type field, which causes the following
code to make bad decisions if connhost[0].host is NULL:

I hadn't noticed (or maybe I forgot) this thread, so when the
same problem was reported at [1]/messages/by-id/18974-575f02b2168b36b3@postgresql.org I just went ahead and pushed the
submitted patch, which is only cosmetically different from your 0001.
Apologies for treading on your toes.

As for the question of how to test this sort of thing, I'm not
too excited about the narrow-gauge test case your 0002 proposes.
What I did for manual testing in [1]/messages/by-id/18974-575f02b2168b36b3@postgresql.org was to hack the postgres_fdw
tests to connect using hostaddr instead of the default. I think
formalizing that sort of approach would yield much better coverage.
I don't have any specific ideas about how to do it, though.
Maybe get our tests to respond to an environment variable that
allows overriding the default choices of connection properties?

regards, tom lane

[1]: /messages/by-id/18974-575f02b2168b36b3@postgresql.org

#4Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Tom Lane (#3)
Re: [PATCH] Fix hostaddr crash during non-blocking cancellation

On Thu, Jul 3, 2025 at 11:54 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

I hadn't noticed (or maybe I forgot) this thread, so when the
same problem was reported at [1] I just went ahead and pushed the
submitted patch, which is only cosmetically different from your 0001.
Apologies for treading on your toes.

No worries, as long as it's fixed I'm happy!

(And many thanks to Greg for the review; sorry for not getting to it
fast enough.)

As for the question of how to test this sort of thing, I'm not
too excited about the narrow-gauge test case your 0002 proposes.
What I did for manual testing in [1] was to hack the postgres_fdw
tests to connect using hostaddr instead of the default. I think
formalizing that sort of approach would yield much better coverage.

I agree that overriding connection defaults probably gets us better
overall coverage -- I just think I got pushback in the past for adding
"multipliers" in that way. But I won't argue against test coverage as
long as we get it in the end. :D

That said, I am planning to get noisier about the lack of "TCP suite".
The number of tests we've discarded just because we don't have a
current place to put them keeps slowly growing, and my long-term
intent with 0002 was to actually add a new place for them. Whatever
formalization we choose, let's please keep a TCP-only cluster
somewhere instead of forcing people to try to find a least-bad suite
to slot new tests into.

Thanks!
--Jacob