Bug 950708 - (CVE-2015-5334) VUL-0: CVE-2015-5334: libressl: Buffer Overflow
(CVE-2015-5334)
VUL-0: CVE-2015-5334: libressl: Buffer Overflow
Status: RESOLVED FIXED
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other openSUSE 13.2
: P3 - Medium : Normal
: ---
Assigned To: Security Team bot
Security Team bot
https://smash.suse.de/issue/157834/
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2015-10-16 08:25 UTC by Andreas Stieger
Modified: 2016-05-18 12:08 UTC (History)
2 users (show)

See Also:
Found By: Security Response Team
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Stieger 2015-10-16 08:25:16 UTC
From http://seclists.org/oss-sec/2015/q4/87

[...]
Buffer Overflow (CVE-2015-5334)
[...]

In order to achieve remote code execution against the vulnerabilities
that we recently discovered in OpenSMTPD (CVE-2015-7687), a memory leak
is needed. Because we could not find one in OpenSMTPD itself, we started
to review the malloc()s and free()s of its libraries, and eventually
found a memory leak in LibreSSL's OBJ_obj2txt() function; we then
realized that this function also contains a buffer overflow (an
off-by-one, usually stack-based).

The vulnerable function OBJ_obj2txt() is reachable through
X509_NAME_oneline() and d2i_X509(), which is called automatically to
decode the X.509 certificates exchanged during an SSL handshake (both
client-side, unless an anonymous mode is used, and server-side, if
client authentication is requested).

These vulnerabilities affect all LibreSSL versions, including LibreSSL
2.0.0 (the first public release) and LibreSSL 2.3.0 (the latest release
at the time of writing). OpenSSL is not affected.

[...]

========================================================================
Buffer Overflow (CVE-2015-5334)
========================================================================

As a result of CVE-2014-3508, OBJ_obj2txt() was modified to "Ensure
that, at every state, |buf| is NUL-terminated." However, in LibreSSL,
the error-handling code at the end of the function may write this
null-terminator out-of-bounds:

489 int
490 OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
491 {
...
516         len = a->length;
517         p = a->data;
518
519         while (len > 0) {
...
522                 for (;;) {
523                         unsigned char c = *p++;
524                         len--;
525                         if ((len == 0) && (c & 0x80))
526                                 goto err;
...
528                                 if (!BN_add_word(bl, c & 0x7f))
529                                         goto err;
...
535                                 if (!bl && !(bl = BN_new()))
536                                         goto err;
537                                 if (!BN_set_word(bl, l))
538                                         goto err;
...
542                                 if (!BN_lshift(bl, bl, 7))
543                                         goto err;
...
546                 }
...
553                                         if (!BN_sub_word(bl, 80))
554                                                 goto err;
...
561                         if (buf_len > 1) {
562                                 *buf++ = i + '0';
563                                 *buf = '\0';
564                                 buf_len--;
565                         }
...
569                 if (use_bn) {
570                         bndec = BN_bn2dec(bl);
571                         if (!bndec)
572                                 goto err;
573                         i = snprintf(buf, buf_len, ".%s", bndec);
574                         if (i == -1)
575                                 goto err;
576                         if (i >= buf_len) {
577                                 buf += buf_len;
578                                 buf_len = 0;
579                         } else {
580                                 buf += i;
581                                 buf_len -= i;
582                         }
...
584                 } else {
585                         i = snprintf(buf, buf_len, ".%lu", l);
586                         if (i == -1)
587                                 goto err;
588                         if (i >= buf_len) {
589                                 buf += buf_len;
590                                 buf_len = 0;
591                         } else {
592                                 buf += i;
593                                 buf_len -= i;
594                         }
...
597                 }
598         }
599
600 out:
...
603         return ret;
604
605 err:
606         ret = 0;
607         buf[0] = '\0';
608         goto out;
609 }

First, in order to trigger this off-by-one buffer overflow, buf must be
increased until it points to the first out-of-bounds character (i.e.,
until buf_len becomes zero):

- on the one hand, this is impossible with the code blocks at lines
  561-564, 579-581, and 591-593;

- on the other hand, this is very easy with the code blocks at lines
  576-578 and 588-590 (the destination buffer is usually quite small;
  for example, it is only 80 bytes long in X509_NAME_oneline()).

Second, the code must branch to the err label:

- the "goto err"s at lines 574-575 and 586-587 are unreachable, because
  snprintf() cannot possibly return -1 here;

- the "goto err" at lines 525-526 is:

  . very easy to reach in LibreSSL <= 2.0.4;

  . impossible to reach in LibreSSL >= 2.0.5, because of the "MSB must
    be clear in the last octet" sanity check that was added to
    c2i_ASN1_OBJECT():

286         /*
287          * Sanity check OID encoding:
288          * - need at least one content octet
289          * - MSB must be clear in the last octet
290          * - can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
291          */
292         if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
293             p[len - 1] & 0x80) {
294                 ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
295                 return (NULL);
296         }

- the remaining "goto err"s are triggered by error conditions in various
  BIGNUM functions:

  . either because of a very large BIGNUM (approximately 64 megabytes,
    which is impossible in the context of an SSL handshake, where X.509
    certificates are limited to 100 kilobytes);

  . or because of an out-of-memory condition (which can be reached
    through the memory leak described above).

This off-by-one buffer overflow allows remote attackers to cause a
denial of service (crash) or possibly execute arbitrary code. However,
when triggered through X509_NAME_oneline() (and therefore d2i_X509()),
this buffer overflow is stack-based and probably not exploitable on
OpenBSD x86, where it appears to always smash the stack canary.



References:
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-5334
http://seclists.org/oss-sec/2015/q4/87
Comment 1 Andreas Stieger 2015-10-16 08:30:53 UTC
OpenBSD Errata for LibreSSL 2.2.4, 2.1.8, 2.0.6 (Oct 15, 2015) for both boo#950708 and boO#950708
http://ftp.openbsd.org/pub/OpenBSD/patches/5.8/common/007_obj2txt.patch.sig
Comment 2 Bernhard Wiedemann 2015-10-16 09:00:42 UTC
This is an autogenerated message for OBS integration:
This bug (950708) was mentioned in
https://build.opensuse.org/request/show/339220 13.2 / libressl
Comment 3 Andreas Stieger 2015-10-16 09:28:11 UTC
(In reply to comment #2)
> https://build.opensuse.org/request/show/339220 13.2 / libressl

Unfortunately, libressl is 2.3.0 affected by both bug 950707 and 950708.

comment #1 references a patch that you could apply to the 2.2.1 version, possibly going for 2.2.4 + this patch for openSUSE 13.2.
Comment 4 Bernhard Wiedemann 2015-10-16 18:00:12 UTC
This is an autogenerated message for OBS integration:
This bug (950708) was mentioned in
https://build.opensuse.org/request/show/339322 Factory / libressl
Comment 5 Bernhard Wiedemann 2015-10-16 20:00:19 UTC
This is an autogenerated message for OBS integration:
This bug (950708) was mentioned in
https://build.opensuse.org/request/show/339338 13.2+Leap:42.1 / libressl.openSUSE_Leap_42.1+libressl
Comment 6 Swamp Workflow Management 2015-10-16 22:01:08 UTC
bugbot adjusting priority
Comment 7 Andreas Stieger 2015-10-19 09:03:21 UTC
Update running, thanks.
Comment 8 Swamp Workflow Management 2015-10-27 12:09:56 UTC
openSUSE-SU-2015:1830-1: An update that fixes two vulnerabilities is now available.

Category: security (moderate)
Bug References: 950707,950708
CVE References: CVE-2015-5333,CVE-2015-5334
Sources used:
openSUSE 13.2 (src):    libressl-2.2.1-2.6.1
Comment 9 Andreas Stieger 2015-10-27 12:32:01 UTC
All done.
Comment 10 Swamp Workflow Management 2015-10-29 16:52:35 UTC
openSUSE-SU-2015:1830-2: An update that fixes two vulnerabilities is now available.

Category: security (moderate)
Bug References: 950707,950708
CVE References: CVE-2015-5333,CVE-2015-5334
Sources used:
openSUSE  (src):    libressl-2.3.0-3.1
Comment 11 Swamp Workflow Management 2016-05-18 12:08:57 UTC
openSUSE-SU-2016:1327-1: An update that solves four vulnerabilities and has two fixes is now available.

Category: security (moderate)
Bug References: 950707,950708,957812,957815,977584,978492
CVE References: CVE-2015-3194,CVE-2015-3195,CVE-2015-5333,CVE-2015-5334
Sources used:
openSUSE 13.2 (src):    libressl-2.2.7-2.13.1