Bugzilla – Bug 950708
VUL-0: CVE-2015-5334: libressl: Buffer Overflow
Last modified: 2016-05-18 12:08:57 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
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
This is an autogenerated message for OBS integration: This bug (950708) was mentioned in https://build.opensuse.org/request/show/339220 13.2 / libressl
(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.
This is an autogenerated message for OBS integration: This bug (950708) was mentioned in https://build.opensuse.org/request/show/339322 Factory / libressl
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
bugbot adjusting priority
Update running, thanks.
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
All done.
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
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