On Sun, 2026-08-09 at 22:15 -0400, Tom Lane wrote:
> 874 if (!OidIsValid(serverid))
> > > > CID 1699896: Null pointer dereferences
> > > > (FORWARD_NULL)
> > > > Passing null pointer "conninfo" to "cstring_to_text", which
> > > > dereferences it.
> 875 values[Anum_pg_subscription_subconninfo - 1]
> =
> 876 CStringGetTextDatum(conninfo);
>
> AFAICS, it's right: if stmt->servername is set while opts.connect is
> not, we'll arrive at this step with serverid filled in but conninfo
> still NULL. Even if there's some upstream reason why that
> combination
> can't occur, this is pretty fragile-looking code.
If serverid is filled, that branch won't be taken.
The code relies on the grammar setting either stmt->servername or stmt-
>conninfo, but not both. I agree that the control flow shouldn't rely
on that, and the code could be more clear anyway. Patch attached.
Regards,
Jeff Davis
From 1506505498b879b736aa2be718667c07b8e9cef3 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 10 Aug 2026 06:59:29 -0700
Subject: [PATCH] Clarify logic in CreateSubscription().
No bug found in previous code, but it unnecessarily relied on grammar
rules. Per complaint from Coverity.
Reported-by: Tom Lane <[email protected]>
Discussion: https://postgr.es/m/[email protected]
Backpatch-through: 19
---
src/backend/commands/subscriptioncmds.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 8e8db08bd93..9938f4b7fe3 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -871,11 +871,17 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
values[Anum_pg_subscription_subretentionactive - 1] =
BoolGetDatum(opts.retaindeadtuples);
values[Anum_pg_subscription_subserver - 1] = ObjectIdGetDatum(serverid);
- if (!OidIsValid(serverid))
+ if (stmt->conninfo)
+ {
+ Assert(stmt->conninfo == conninfo && !OidIsValid(serverid));
values[Anum_pg_subscription_subconninfo - 1] =
- CStringGetTextDatum(conninfo);
+ CStringGetTextDatum(stmt->conninfo);
+ }
else
+ {
+ Assert(OidIsValid(serverid));
nulls[Anum_pg_subscription_subconninfo - 1] = true;
+ }
if (opts.slot_name)
values[Anum_pg_subscription_subslotname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(opts.slot_name));
--
2.43.0