summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFujii Masao2026-08-19 03:31:00 +0000
committerFujii Masao2026-08-19 03:33:59 +0000
commitb57f962201b248c65d6034176871b28bc04072dc (patch)
treeaa819baa16b70d01ba90d7fe7b3a5692341243de
parent402e9624444b3b3c3f75c90d3b3d847dcfa1b8f9 (diff)
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
-rw-r--r--src/bin/psql/command.c4
-rw-r--r--src/bin/psql/psqlscanslash.l15
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;
}