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

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
This commit is contained in:
Fujii Masao
2026-08-19 12:31:00 +09:00
parent e8d079313a
commit 3d41f014f1
2 changed files with 16 additions and 3 deletions

View File

@@ -238,7 +238,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;

View File

@@ -481,7 +481,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)
@@ -512,7 +512,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
@@ -520,6 +520,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;
}