public inbox for [email protected]  
help / color / mirror / Atom feed
From: Shruthi Gowda <[email protected]>
To: PostgreSQL Development <[email protected]>
Subject: [BUG] CRASH: ECPGprepared_statement() and ECPGdeallocate_all() when connection is NULL
Date: Mon, 8 Dec 2025 21:08:56 +0530
Message-ID: <CAASxf_P1F75Ck+0qyb10auT+BORupOM4yigXBnm7aWRNx1LYcA@mail.gmail.com> (raw)

Hi,

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.

The issue is reproducible on the MASTER branch and affects older versions
up to v13.

The issue can be reproduced by modifying existing test cases, such as
src/interfaces/ecpg/test/sql/execute.pgc or
src/interfaces/ecpg/test/sql/desc.pgc. The general method is to skip the EXEC
SQL CONNECT statement (or intentionally force the connection to fail).

To specifically isolate the crash in ECPGdeallocate_all() and prevent the
program from hitting the ECPGprepared_statement() crash first, modify the
desc.pgc test file by moving the EXEC SQL DEALLOCATE ALL statement to an
earlier point

*Seg fault in ECPGprepared_statement():*
[434574]: ECPGdebug: set to 1
[434574]: ECPGconnect: opening database ecpg1_regression on <DEFAULT> port
<DEFAULT>
[434574]: ECPGconnect: connection to server on socket "/tmp/.s.PGSQL.5444"
failed: FATAL:  database "ecpg1_regression" does not exist
[434574]: ecpg_finish: connection main closed
[434574]: raising sqlcode -402 on line 24: could not connect to database
"ecpg1_regression" on line 24
SQL error: could not connect to database "ecpg1_regression" on line 24
[434574]: raising sqlcode -220 on line 25: connection "NULL" does not exist
on line 25
SQL error: connection "NULL" does not exist on line 25
[434574]: raising sqlcode -220 on line 26: connection "NULL" does not exist
on line 26
SQL error: connection "NULL" does not exist on line 26
[434574]: raising sqlcode -220 on line 29: connection "NULL" does not exist
on line 29
SQL error: connection "NULL" does not exist on line 29
[434574]: raising sqlcode -220 on line 32: connection "NULL" does not exist
on line 32
SQL error: connection "NULL" does not exist on line 32
[434574]: raising sqlcode -220 on line 35: connection "NULL" does not exist
on line 35
SQL error: connection "NULL" does not exist on line 35
Inserted 0 tuples via execute immediate
[434574]: raising sqlcode -220 on line 40: connection "NULL" does not exist
on line 40
SQL error: connection "NULL" does not exist on line 40
[434574]: raising sqlcode -220 on line 41: connection "NULL" does not exist
on line 41
SQL error: connection "NULL" does not exist on line 41
Inserted 0 tuples via prepared execute
[434574]: raising sqlcode -220 on line 45: connection "NULL" does not exist
on line 45
SQL error: connection "NULL" does not exist on line 45
[434574]: raising sqlcode -220 on line 49: connection "NULL" does not exist
on line 49
SQL error: connection "NULL" does not exist on line 49

Program received signal SIGSEGV, Segmentation fault.
0x0000fffff7f92654 in ecpg_find_prepared_statement (name=0xaaaaaaaa1aa8
"f", con=0x0, prev_=0x0) at prepare.c:277
277             for (this = con->prep_stmts, prev = NULL;
(gdb) bt
#0  0x0000fffff7f92654 in ecpg_find_prepared_statement (name=0xaaaaaaaa1aa8
"f", con=0x0, prev_=0x0) at prepare.c:277
#1  0x0000fffff7f92aa8 in ecpg_prepared (name=0xaaaaaaaa1aa8 "f", con=0x0)
at prepare.c:393
#2  0x0000fffff7f92afc in ECPGprepared_statement (connection_name=0x0,
name=0xaaaaaaaa1aa8 "f", lineno=53)
    at prepare.c:404

#3  0x0000aaaaaaaa0f74 in main () at
/home/shrkc/work/postgres/inst/bin/execute.pgc:52



*Seg fault in ECPGdeallocate_all() :*


Program received signal SIGSEGV, Segmentation fault.
0x0000fffff7f92a2c in ecpg_deallocate_all_conn (lineno=25,
c=ECPG_COMPAT_PGSQL, con=0x0) at prepare.c:372
372             while (con->prep_stmts)
(gdb) bt
#0  0x0000fffff7f92a2c in ecpg_deallocate_all_conn (lineno=25,
c=ECPG_COMPAT_PGSQL, con=0x0) at prepare.c:372
#1  0x0000fffff7f92a78 in ECPGdeallocate_all (lineno=25, compat=0,
connection_name=0x0) at prepare.c:384
#2  0x0000aaaaaaaa0e60 in main () at
/home/shrkc/work/postgres/inst/bin/desc.pgc:25


Please find the proposed patch attached below for your review.


Thanks & Regards,

Shruthi K C

EnterpriseDB: http://www.enterprisedb.com


Attachments:

  [application/octet-stream] v1-0001-Fix-Add-connection-validation-to-ECPGdeallocate_a.patch (1.9K, 3-v1-0001-Fix-Add-connection-validation-to-ECPGdeallocate_a.patch)
  download | inline diff:
From 2f57007f201c5c65b21d3bab866c7488c966a494 Mon Sep 17 00:00:00 2001
From: shruthi gowda <[email protected]>
Date: Mon, 8 Dec 2025 15:20:08 +0000
Subject: [PATCH v1] Fix: Add connection validation to ECPGdeallocate_all() and
 ECPGprepared_statement()

This commit adds the required connection validation at the start of these
functions to ensure they handle a disconnected state gracefully without
crashing the application.
---
 src/interfaces/ecpg/ecpglib/prepare.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c
index 5c7c5397535..96be4396415 100644
--- a/src/interfaces/ecpg/ecpglib/prepare.c
+++ b/src/interfaces/ecpg/ecpglib/prepare.c
@@ -381,8 +381,16 @@ 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 (!con)
+	{
+		ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
+				   connection_name ? connection_name : ecpg_gettext("NULL"));
+		return false;
+	}
+	return ecpg_deallocate_all_conn(lineno, compat, con);
 }
 
 char *
@@ -399,9 +407,17 @@ 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 (!con)
+	{
+		ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
+				   connection_name ? connection_name : ecpg_gettext("NULL"));
+		return NULL;
+	}
 
-	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]
  Subject: Re: [BUG] CRASH: ECPGprepared_statement() and ECPGdeallocate_all() when connection is NULL
  In-Reply-To: <CAASxf_P1F75Ck+0qyb10auT+BORupOM4yigXBnm7aWRNx1LYcA@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