Bug 1303832 (CVE-2016-0773)

Summary: CVE-2016-0773 postgresql: case insensitive range handling integer overflow leading to buffer overflow
Product: [Other] Security Response Reporter: Andrej Nemec <anemec>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: bagnara, bkearney, cpelland, dajohnso, databases-maint, gblomqui, gmccullo, gtanzill, hhorak, jfrey, jhardy, jorton, jprause, jskarvad, mefoster, meissner, mmaslano, obarenbo, ppisar, praiskup, roliveri, security-response-team, slong, thomas, tkasparek, tlestach, wart, xlecauch
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: postgresql 9.5.1, postgresql 9.4.6, postgresql 9.3.11, postgresql 9.2.15, postgresql 9.1.20 Doc Type: Bug Fix
Doc Text:
An integer overflow flaw, leading to a heap-based buffer overflow, was found in the PostgreSQL handling code for regular expressions. A remote attacker could use a specially crafted regular expression to cause PostgreSQL to crash or possibly execute arbitrary code.
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-06-08 02:48:05 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1306635, 1308597, 1308598, 1308599, 1308600, 1308601, 1308602, 1308604, 1308605, 1308615, 1330296, 1330297    
Bug Blocks: 1303834    

Description Andrej Nemec 2016-02-02 07:43:10 UTC
A vulnerability was found in a way postgresql processes specially crafted regular expressions.

Purpose-crafted regular expressions elicited an integer overflow when
computing a heap allocation size, and the server proceeded to write past the
end of the undersized buffer. This could reliably crash the server, and we
have not ruled out the viability of attacks that lead to privilege escalation.
If an application accepts arbitrary regular expressions from its users, they
can exploit this without otherwise having access to query the database.

Acknowledgements:

Red Hat would like to thank PostgreSQL upstream for reporting this issue. Upstream acknowledges Tom Lane and Greg Stark as the original reporters.

Comment 7 Andrej Nemec 2016-02-11 13:55:43 UTC
Created postgresql tracking bugs for this issue:

Affects: fedora-all [bug 1306635]

Comment 8 Andrej Nemec 2016-02-11 13:56:07 UTC
Public via http://www.postgresql.org/about/news/1644/

Comment 9 Tomas Hoger 2016-02-15 15:16:07 UTC
The issue problem here is an integer overflow in the range() function in regc_locale.c.  It is triggered when doing a case insensitive regular expression match with a character range identifying many characters.  The following code is used to compute the size of the array that will hold all characters specified by the range:

  nchrs = (b - a + 1) * 2 + 4;

a and b are characters for the start and end of the range.  Their difference in multiplied by 2 to ensure there's enough space to store upper- or lower-case counterpart of each character in the range.

All variables are signed int, so this overflows to a small positive value when size of the range is 2^31.  That leads to allocation of an insufficiently sized buffer.

Additionally, it's sufficient to have the range have size of 2^30, which leads to negative nchrs value, and causes the getcvec() function in regc_cvec.c re-use existing cvec with an insufficiently sized buffer (because nchrs <= v->cv->chrspace is true).

There is another problem affecting 32bit systems.  The newcvec() function (also in regc_cvec.c) also fails to protect against integer overflows before doing actual memory allocation.  Each character in the range is represented by a chr type value, which is a 32 bit integer type.  Therefore, the number of characters to be stored is multiplied by sizeof(chr) to get the required buffer size in bytes.  The newcvec() function internally uses variables of type size_t, which is 32 bit type on 32bit systems.  Therefore, a range with 2^29 characters can trigger overflow in newcvec().

On 64bit systems, size_t is 64 bit.  Hence only negative nchars values may trigger integer overflow in newcvec(), as they become large positive after conversion to size_t.  It's unclear if negative nchars is possible in newcvec() given the getcvec()'s attempt to re-use existing cvec when one is already allocated.  On 64bit systems, the newcvec() overflow does not reduce the range size required to trigger overflow.

After cvec is allocated, the range() function initializes its chrs[] array.  It stores every character in the range and optionally its lower- or upper-case counterpart if one exists.  If integer overflow occurred during memory allocation, this initialization needs to write over at least 2GB (2^29 * sizeof(chr)) of memory 32bit systems and 4GB on 64bit systems.  Hence, the initialization complicates exploitation as it is likely to attempt to write into unmapped memory pages, leading to process crash.  PostgreSQL server side processed do not use threads, so other thread won't work with corrupted memory while array initialization is still in progress.

Overall, this looks like a borderline Moderate/Important issue.  Database user with SQL access can easily use this to trigger server restart, achieving code execution seems lot more difficult.

Comment 15 Tomas Hoger 2016-02-15 19:55:44 UTC
The regex handling code in PostgreSQL comes from the TCL.  This issue did not affect tcl packages as shipped in Red Hat Enterprise Linux and Fedora.  The chr type is 16bit, hence the maximum range size is limited to 2^16, which is not sufficient to trigger the overflow.  Note that TCL can be built with 32bit chr type depending on the value of TCL_UTF_MAX macro.  The default value is 3, which implies the use of 16bit chr.  Other valid value is 6, but that is considered experimental upstream and not recommended.  See tcl.h for details.

It does not seem TCL upstream has corrected this issue yet.  If any of the TCL packages maintainers have account in upstream bug tracker, feel free to open a bug to ensure TCL upstream is aware of the issue.

The TCL regex handling code is also used in SWI-Prolog / XPCE.  It is possible to trigger integer overflow there, but the assert() in addchr() (see regc_cvec.c) seems to prevent buffer overflow and reduces impact to abort.  Notified upstream via:

https://github.com/SWI-Prolog/packages-xpce/issues/2

Comment 17 Jaroslav Škarvada 2016-02-16 10:07:54 UTC
(In reply to Tomas Hoger from comment #15)
> It does not seem TCL upstream has corrected this issue yet.  If any of the
> TCL packages maintainers have account in upstream bug tracker, feel free to
> open a bug to ensure TCL upstream is aware of the issue.

Created TCL upstream ticket:
http://core.tcl.tk/tcl/tktview/67fcef9acaf767003180ee05b8a35ef8ea6ae049

Comment 18 Fedora Update System 2016-02-23 19:22:37 UTC
postgresql-9.4.6-1.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report.

Comment 19 Fedora Update System 2016-02-25 08:53:58 UTC
postgresql-9.4.6-1.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report.

Comment 20 errata-xmlrpc 2016-03-02 16:22:10 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 6

Via RHSA-2016:0347 https://rhn.redhat.com/errata/RHSA-2016-0347.html

Comment 21 errata-xmlrpc 2016-03-02 16:47:03 UTC
This issue has been addressed in the following products:

  Red Hat Software Collections for Red Hat Enterprise Linux 7.1 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7
  Red Hat Software Collections for Red Hat Enterprise Linux 7.2 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 6.6 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 6.7 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 6

Via RHSA-2016:0348 https://rhn.redhat.com/errata/RHSA-2016-0348.html

Comment 22 errata-xmlrpc 2016-03-02 17:02:57 UTC
This issue has been addressed in the following products:

  Red Hat Software Collections for Red Hat Enterprise Linux 7.1 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7
  Red Hat Software Collections for Red Hat Enterprise Linux 7.2 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 6.6 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 6.7 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 6

Via RHSA-2016:0349 https://rhn.redhat.com/errata/RHSA-2016-0349.html

Comment 23 errata-xmlrpc 2016-03-02 17:20:15 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2016:0346 https://rhn.redhat.com/errata/RHSA-2016-0346.html

Comment 26 errata-xmlrpc 2016-05-12 14:56:40 UTC
This issue has been addressed in the following products:

  Red Hat Satellite 5.7

Via RHSA-2016:1060 https://rhn.redhat.com/errata/RHSA-2016-1060.html