This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch backport_cve
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit ae4c7c1aedc00b1fc28926dd9d3c31f08dfba4f6
Author: Michael Paquier <[email protected]>
AuthorDate: Mon Aug 10 06:38:24 2026 -0700

    ecpg: Fix out-of-bound writes due to processing of invalid bytea data
    
    ECPG assumes that any bytea data it receives from a backend starts with
    '\x' as its first two bytes, but a check was missed to enforce that.  A
    rogue server sending some garbage bytea data would be able to crash a
    client, resulting in a client-side DoS, in the most common cases.
    
    Reported-by: ylwangtju <[email protected]>
    Backpatch-through: 14
    Security: CVE-2026-16241
---
 src/interfaces/ecpg/ecpglib/data.c                 |  7 ++++++
 src/interfaces/ecpg/ecpglib/error.c                |  7 ++++++
 src/interfaces/ecpg/include/ecpgerrno.h            |  1 +
 src/interfaces/ecpg/test/expected/sql-bytea.c      | 27 ++++++++++++++++++----
 src/interfaces/ecpg/test/expected/sql-bytea.stderr | 24 ++++++++++++++++++-
 src/interfaces/ecpg/test/sql/bytea.pgc             |  5 ++++
 6 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/src/interfaces/ecpg/ecpglib/data.c 
b/src/interfaces/ecpg/ecpglib/data.c
index fa562767585..a63d465acf4 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -526,6 +526,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int 
act_field, int lineno,
                                                                        
src_size,
                                                                        
dec_size;
 
+                                               if (size < 2 || pval[0] != '\\' 
|| pval[1] != 'x')
+                                               {
+                                                       ecpg_raise(lineno, 
ECPG_BYTEA_FORMAT,
+                                                                          
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
+                                                       return false;
+                                               }
+
                                                dst_size = 
ecpg_hex_enc_len(varcharsize);
                                                src_size = size - 2;    /* 
exclude backslash + 'x' */
                                                dec_size = src_size < dst_size 
? src_size : dst_size;
diff --git a/src/interfaces/ecpg/ecpglib/error.c 
b/src/interfaces/ecpg/ecpglib/error.c
index 26fdcdb69e9..fba8b4468dd 100644
--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -130,6 +130,13 @@ ecpg_raise(int line, int code, const char *sqlstate, const 
char *str)
                                         ecpg_gettext("inserting an array of 
variables is not supported on line %d"), line);
                        break;
 
+               case ECPG_BYTEA_FORMAT:
+                       snprintf(sqlca->sqlerrm.sqlerrmc, 
sizeof(sqlca->sqlerrm.sqlerrmc),
+                       /*------
+                          translator: this string will be truncated at 149 
characters expanded.  */
+                                        ecpg_gettext("invalid input syntax for 
type bytea: \"%s\", on line %d"), str, line);
+                       break;
+
                case ECPG_NO_CONN:
                        snprintf(sqlca->sqlerrm.sqlerrmc, 
sizeof(sqlca->sqlerrm.sqlerrmc),
                        /*------
diff --git a/src/interfaces/ecpg/include/ecpgerrno.h 
b/src/interfaces/ecpg/include/ecpgerrno.h
index c4bc526463d..d8216b365b6 100644
--- a/src/interfaces/ecpg/include/ecpgerrno.h
+++ b/src/interfaces/ecpg/include/ecpgerrno.h
@@ -32,6 +32,7 @@
 #define ECPG_NO_ARRAY                  -214
 #define ECPG_DATA_NOT_ARRAY            -215
 #define ECPG_ARRAY_INSERT              -216
+#define ECPG_BYTEA_FORMAT              -217
 
 #define ECPG_NO_CONN                   -220
 #define ECPG_NOT_CONN                  -221
diff --git a/src/interfaces/ecpg/test/expected/sql-bytea.c 
b/src/interfaces/ecpg/test/expected/sql-bytea.c
index 8338c6008dd..901594a6f63 100644
--- a/src/interfaces/ecpg/test/expected/sql-bytea.c
+++ b/src/interfaces/ecpg/test/expected/sql-bytea.c
@@ -356,17 +356,36 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 115 "bytea.pgc"
 
+
+       /* Test for invalid bytea format */
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select '' :: text", 
ECPGt_EOIT, 
+       ECPGt_bytea,&(recv_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct 
bytea_2), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 118 "bytea.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 118 "bytea.pgc"
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select '\\\\a1234' :: 
text", ECPGt_EOIT, 
+       ECPGt_bytea,&(recv_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct 
bytea_2), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 119 "bytea.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 119 "bytea.pgc"
+
+
        { ECPGtrans(__LINE__, NULL, "commit");
-#line 116 "bytea.pgc"
+#line 121 "bytea.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 116 "bytea.pgc"
+#line 121 "bytea.pgc"
 
        { ECPGdisconnect(__LINE__, "CURRENT");
-#line 117 "bytea.pgc"
+#line 122 "bytea.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 117 "bytea.pgc"
+#line 122 "bytea.pgc"
 
 
        return 0;
diff --git a/src/interfaces/ecpg/test/expected/sql-bytea.stderr 
b/src/interfaces/ecpg/test/expected/sql-bytea.stderr
index cb828a76020..58589474856 100644
--- a/src/interfaces/ecpg/test/expected/sql-bytea.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-bytea.stderr
@@ -181,7 +181,29 @@ SQL error: invalid statement name "cursor1" on line 82
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 115: OK: DROP TABLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ECPGtrans on line 116: action "commit"; connection "ecpg1_regression"
+[NO_PID]: ecpg_execute on line 118: query: select '' :: text; with 0 
parameter(s) on connection ecpg1_regression
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 118: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 118: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 118: RESULT:  offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode -217 on line 118: invalid input syntax for type 
bytea: "", on line 118
+[NO_PID]: sqlca: code: -217, state: 42804
+SQL error: invalid input syntax for type bytea: "", on line 118
+[NO_PID]: ecpg_execute on line 119: query: select '\\a1234' :: text; with 0 
parameter(s) on connection ecpg1_regression
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 119: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 119: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 119: RESULT: \\a1234 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode -217 on line 119: invalid input syntax for type 
bytea: "\\a1234", on line 119
+[NO_PID]: sqlca: code: -217, state: 42804
+SQL error: invalid input syntax for type bytea: "\\a1234", on line 119
+[NO_PID]: ECPGtrans on line 121: action "commit"; connection "ecpg1_regression"
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: deallocate_one on line 0: name sel_stmt
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/sql/bytea.pgc 
b/src/interfaces/ecpg/test/sql/bytea.pgc
index e8741231194..da9152758a2 100644
--- a/src/interfaces/ecpg/test/sql/bytea.pgc
+++ b/src/interfaces/ecpg/test/sql/bytea.pgc
@@ -113,6 +113,11 @@ while (0)
        dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]);
 
        exec sql drop table test;
+
+       /* Test for invalid bytea format */
+       exec sql select ''::text into :recv_buf[0];
+       exec sql select '\\a1234'::text into :recv_buf[0];
+
        exec sql commit;
        exec sql disconnect;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to