postgres.git / summary / log / commit / refs
commit b57f962201b248c65d6034176871b28bc04072dc
Author: Fujii Masao <fujii@postgresql.org>
Date: Wed Aug 19 03:31:00 2026 +0000
psql: Avoid returning oom_buffer from psql slash command scanner
psql_scan_slash_command() builds the command name in a local
PQExpBufferData and returns the buffer's data pointer to its caller. If
either the initial allocation or a later enlargement failed, that data
pointer could be the static PQExpBuffer OOM buffer rather than malloc-owned
storage. HandleSlashCmds() could then eventually pass it to free(), causing
undefined behavior.
Detect a broken command-name buffer before returning it, report OOM, and
return NULL instead. Teach HandleSlashCmds() to treat a NULL command name
as a command error before trying to compare or dispatch it.
Backpatch to all supported versions.
Reported-by: Junwang Zhao <zhjwpku@gmail.com>
Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Discussion: https://postgr.es/m/CAHGQGwEh3R3=1tx_a5=fTDJ+ycuwxWMEn6bG_Yt4B5P+hE7AVw@mail.gmail.com
Backpatch-through: 14
src/bin/psql/command.c | 4 +++-
src/bin/psql/psqlscanslash.l | 15 +++++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index ae3ab3295d5..be9e3b035e2 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -236,7 +236,9 @@ HandleSlashCmds(PsqlScanState scan_state,
* If we are in "restricted" mode, the only allowable backslash command is
* \unrestrict (to exit restricted mode).
*/
- if (restricted && strcmp(cmd, "unrestrict") != 0)
+ if (cmd == NULL)
+ status = PSQL_CMD_ERROR;
+ else if (restricted && strcmp(cmd, "unrestrict") != 0)
{
pg_log_error("backslash commands are restricted; only \\unrestrict is allowed");
status = PSQL_CMD_ERROR;
diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l
index a917d1ec180..0af91cba6bd 100644
--- a/src/bin/psql/psqlscanslash.l
+++ b/src/bin/psql/psqlscanslash.l
@@ -479,7 +479,7 @@ other .
* has been consumed through the leading backslash.
*
* The return value is a malloc'd copy of the command name, as parsed off
- * from the input.
+ * from the input, or NULL on out-of-memory.
*/
char *
psql_scan_slash_command(PsqlScanState state)
@@ -510,7 +510,7 @@ psql_scan_slash_command(PsqlScanState state)
/* And lex. */
yylex(NULL, state->scanner);
- /* There are no possible errors in this lex state... */
+ /* There are no possible syntax errors in this lex state... */
/*
* In case the caller returns to using the regular SQL lexer, reselect the
@@ -518,6 +518,17 @@ psql_scan_slash_command(PsqlScanState state)
*/
psql_scan_reselect_sql_lexer(state);
+ /*
+ * yylex() appends command-name text to mybuf, so a buffer enlargement
+ * failure during lexing can leave mybuf broken even if initialization
+ * succeeded.
+ */
+ if (PQExpBufferDataBroken(mybuf))
+ {
+ pg_log_error("out of memory");
+ return NULL;
+ }
+
return mybuf.data;
}
[parent: 402e9624444b]