1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

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 <ylwangtju@qq.com>
Backpatch-through: 14
Security: CVE-2026-16241
This commit is contained in:
Michael Paquier
2026-08-10 06:38:11 -07:00
committed by Noah Misch
parent 028ee716a7
commit a14ba29b15
6 changed files with 67 additions and 6 deletions

View File

@@ -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;

View File

@@ -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),
/*------

View File

@@ -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

View File

@@ -356,17 +356,36 @@ if (sqlca.sqlcode < 0) sqlprint();}
if (sqlca.sqlcode < 0) sqlprint();}
#line 115 "bytea.pgc"
{ ECPGtrans(__LINE__, NULL, "commit");
#line 116 "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 116 "bytea.pgc"
#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 121 "bytea.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
#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;

View File

@@ -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

View File

@@ -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;