public inbox for [email protected]  
help / color / mirror / Atom feed
From: Shruthi Gowda <[email protected]>
To: Fujii Masao <[email protected]>
Cc: Tom Lane <[email protected]>
Cc: PostgreSQL Development <[email protected]>
Subject: Re: [BUG] CRASH: ECPGprepared_statement() and ECPGdeallocate_all() when connection is NULL
Date: Mon, 19 Jan 2026 17:38:29 +0530
Message-ID: <CAASxf_OGWD7PA5TMEh2MdF2YxN8V3ByLhnFJ=uw0hKr33sgqAw@mail.gmail.com> (raw)
In-Reply-To: <CAHGQGwHAPXexiGaHMkDDRF7cPBr_3fgCNdT4n2+1UjaEU++BAQ@mail.gmail.com>
References: <CAASxf_P1F75Ck+0qyb10auT+BORupOM4yigXBnm7aWRNx1LYcA@mail.gmail.com>
	<[email protected]>
	<CAASxf_P5f=Frf8S7rN9BzphtCLoeN9vFuh-V7ukotOQZU54g+w@mail.gmail.com>
	<CAHGQGwHAPXexiGaHMkDDRF7cPBr_3fgCNdT4n2+1UjaEU++BAQ@mail.gmail.com>

On Thu, Jan 8, 2026 at 9:32 PM Fujii Masao <[email protected]> wrote:

> On Thu, Jan 8, 2026 at 3:00 AM Shruthi Gowda <[email protected]> wrote:
> >
> >
> > On Mon, Dec 8, 2025 at 9:39 PM Tom Lane <[email protected]> wrote:
> >>
> >> Shruthi Gowda <[email protected]> writes:
> >> > The ECPG application crashes with a segmentation fault when calling
> >> > specific deallocation or prepared statement functions without an
> >> > established database connection. This is caused by a missing NULL
> check on
> >> > the connection handle before attempting to access it.
> >>
> >> Hmm ... poking around, I see several other places that aren't checking
> >> the result of ecpg_get_connection.  Shouldn't we tighten them all?
> >>
> >>                         regards, tom lane
> >
> >
> > I agree. I’ve reviewed all occurrences of ecpg_get_connection() and
> noted that, in most instances, it is followed by ecpg_init(), which
> validates the connection and returns immediately if the connection is NULL.
>
> Why did you add this check instead of calling ecpg_init()?
> Wouldn't it be better and sufficient to use ecpg_init() to validate
> the connection?
>
> + con = ecpg_get_connection(connection_name);
> + if (!con)
> + {
> + ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
> +    connection_name ? connection_name : ecpg_gettext("NULL"));
>
>
 Thanks for the feedback, Fujii. I agree—using ecpg_init() is a more
consistent approach and aligns with how this is handled in other parts of
the code.
I have updated the patch to use ecpg_init() for validation. Please find the
revised version attached.
The patch works for MASTER and all the back branches.

Thanks & Regards,

Shruthi K C

EnterpriseDB: http://www.enterprisedb.com


Attachments:

  [application/octet-stream] v3-0001-Add-missing-connection-validation-in-ECPG.patch (2.8K, 3-v3-0001-Add-missing-connection-validation-in-ECPG.patch)
  download | inline diff:
From 3267a4da8d41761a6ddb1880e57dbfb109a3eeb3 Mon Sep 17 00:00:00 2001
From: shruthi gowda <[email protected]>
Date: Mon, 19 Jan 2026 10:32:23 +0000
Subject: [PATCH v3] Add missing connection validation in ECPG

Ensure that ECPG connections are validated before use to prevent
application crashes. This allows the system to handle disconnected
states gracefully by throwing a proper error instead of
segfaulting.
---
 src/interfaces/ecpg/ecpglib/descriptor.c |  9 +++++++--
 src/interfaces/ecpg/ecpglib/prepare.c    | 17 +++++++++++++----
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 39cd5130ec9..128fddd167c 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -235,6 +235,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 {
 	va_list		args;
 	PGresult   *ECPGresult;
+	struct connection *con;
 	enum ECPGdtype type;
 	int			ntuples,
 				act_tuple;
@@ -249,8 +250,12 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 		return false;
 	}
 
+	con = ecpg_get_connection(NULL);
+	if (!ecpg_init(con, NULL, lineno))
+		return false;
+
 	va_start(args, index);
-	ecpg_init_sqlca(sqlca);
+
 	ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
 	if (!ECPGresult)
 	{
@@ -506,7 +511,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 #endif
 
 		/* desperate try to guess something sensible */
-		stmt.connection = ecpg_get_connection(NULL);
+		stmt.connection = con;
 		ecpg_store_result(ECPGresult, index, &stmt, &data_var);
 
 #ifdef HAVE_USELOCALE
diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c
index 5c7c5397535..6bcd34cdf81 100644
--- a/src/interfaces/ecpg/ecpglib/prepare.c
+++ b/src/interfaces/ecpg/ecpglib/prepare.c
@@ -381,8 +381,13 @@ ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con)
 bool
 ECPGdeallocate_all(int lineno, int compat, const char *connection_name)
 {
-	return ecpg_deallocate_all_conn(lineno, compat,
-									ecpg_get_connection(connection_name));
+	struct connection *con;
+
+	con = ecpg_get_connection(connection_name);
+	if (!ecpg_init(con, connection_name, lineno))
+		return false;
+
+	return ecpg_deallocate_all_conn(lineno, compat, con);
 }
 
 char *
@@ -399,9 +404,13 @@ ecpg_prepared(const char *name, struct connection *con)
 char *
 ECPGprepared_statement(const char *connection_name, const char *name, int lineno)
 {
-	(void) lineno;				/* keep the compiler quiet */
+	struct connection *con;
+
+	con = ecpg_get_connection(connection_name);
+	if (!ecpg_init(con, connection_name, lineno))
+		return false;
 
-	return ecpg_prepared(name, ecpg_get_connection(connection_name));
+	return ecpg_prepared(name, con);
 }
 
 /*
-- 
2.43.0



reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected]
  Subject: Re: [BUG] CRASH: ECPGprepared_statement() and ECPGdeallocate_all() when connection is NULL
  In-Reply-To: <CAASxf_OGWD7PA5TMEh2MdF2YxN8V3ByLhnFJ=uw0hKr33sgqAw@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox