1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Revoke support for strxfrm() that write past the specified array length.

This formalizes a decision implicit in commit
4ea51cdfe8 and adds clean detection of
affected systems.  Vendor updates are available for each such known bug.
Back-patch to 9.5, where the aforementioned commit first appeared.
This commit is contained in:
Noah Misch
2015-07-08 20:44:21 -04:00
parent b28244abe5
commit be8b06c364
5 changed files with 70 additions and 10 deletions

View File

@ -854,6 +854,64 @@ IsoLocaleName(const char *winlocname)
#endif /* WIN32 && LC_MESSAGES */
/*
* Detect aging strxfrm() implementations that, in a subset of locales, write
* past the specified buffer length. Affected users must update OS packages
* before using PostgreSQL 9.5 or later.
*
* Assume that the bug can come and go from one postmaster startup to another
* due to physical replication among diverse machines. Assume that the bug's
* presence will not change during the life of a particular postmaster. Given
* those assumptions, call this no less than once per postmaster startup per
* LC_COLLATE setting used. No known-affected system offers strxfrm_l(), so
* there is no need to consider pg_collation locales.
*/
void
check_strxfrm_bug(void)
{
char buf[32];
const int canary = 0x7F;
bool ok = true;
/*
* Given a two-byte ASCII string and length limit 7, 8 or 9, Solaris 10
* 05/08 returns 18 and modifies 10 bytes. It respects limits above or
* below that range.
*
* The bug is present in Solaris 8 as well; it is absent in Solaris 10
* 01/13 and Solaris 11.2. Affected locales include is_IS.ISO8859-1,
* en_US.UTF-8, en_US.ISO8859-1, and ru_RU.KOI8-R. Unaffected locales
* include de_DE.UTF-8, de_DE.ISO8859-1, zh_TW.UTF-8, and C.
*/
buf[7] = canary;
(void) strxfrm(buf, "ab", 7);
if (buf[7] != canary)
ok = false;
/*
* illumos bug #1594 was present in the source tree from 2010-10-11 to
* 2012-02-01. Given an ASCII string of any length and length limit 1,
* affected systems ignore the length limit and modify a number of bytes
* one less than the return value. The problem inputs for this bug do not
* overlap those for the Solaris bug, hence a distinct test.
*
* Affected systems include smartos-20110926T021612Z. Affected locales
* include en_US.ISO8859-1 and en_US.UTF-8. Unaffected locales include C.
*/
buf[1] = canary;
(void) strxfrm(buf, "a", 1);
if (buf[1] != canary)
ok = false;
if (!ok)
ereport(ERROR,
(errcode(ERRCODE_SYSTEM_ERROR),
errmsg_internal("strxfrm(), in locale \"%s\", writes past the specified array length",
setlocale(LC_COLLATE, NULL)),
errhint("Apply system library package updates.")));
}
/*
* Cache mechanism for collation information.
*