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

Guard against overlength time zone abbreviations in to_char().

While typical abbreviations are only a few bytes long, a user-supplied
time_zone setting could specify a much longer abbreviation, enough to
overflow to_char's allocation of 12 bytes per format character. If so,
throw an error in the same style as commit 9241c84cb (CVE-2015-0241).

Reported-by: Hcamael <baiyjrh@gmail.com>
Reported-by: Amjad Shahzad <amjadshahzad2000@gmail.com>
Reported-by: Tan Zhen of AntAISecurityLab <TanZhen.AntAI@outlook.com>
Reported-by: Tomer Fichman <tomer@irregular.com>
Reported-by: Zheng Yu <zheng@depthfirst.com>
Reported-by: Amy Burnett (OpenAI Codex Security)
Reported-by: Rick de Jager <rick@v12.sh>
Reported-by: Heewon Song <asteria121@78researchlab.com>
Reported-by: Sylvie Mayer <smayer@cloudflare.com>
Reported-by: Aleksander Alekseev <aleksander@tigerdata.com>
Reported-by: Hillai Ben Sasson <hillai.bensasson@wiz.io>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Backpatch-through: 14
Security: CVE-2026-14669
This commit is contained in:
Tom Lane
2026-08-10 06:38:17 -07:00
committed by Noah Misch
parent 3e85b223b0
commit 12a6206864

View File

@@ -2996,10 +2996,18 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (tmtcTzn(in))
{
/* We assume here that timezone names aren't localized */
/*
* We assume here that timezone abbreviations aren't
* localized, so ASCII-only downcasing is sufficient.
*/
char *p = asc_tolower_z(tmtcTzn(in));
strcpy(s, p);
if (strlen(p) <= n->key->len * DCH_MAX_ITEM_SIZ)
strcpy(s, p);
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("time zone format value too long")));
pfree(p);
s += strlen(s);
}
@@ -3008,7 +3016,14 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (tmtcTzn(in))
{
strcpy(s, tmtcTzn(in));
const char *p = tmtcTzn(in);
if (strlen(p) <= n->key->len * DCH_MAX_ITEM_SIZ)
strcpy(s, p);
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("time zone format value too long")));
s += strlen(s);
}
break;