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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user