CVE-2015-5291: remote heap corruption in ARM mbed TLS / PolarSSL

See this PDF file file for an analysis of CVE-2015-5291 and related weaknesses in the library’s code.

8 vulnerabilities, ranging from corner cases to remote heap corruption in a fairly default configuration (which is CVE-2015-5291), found in ARM mbed TLS / PolarSSL were submitted between 7 September 2015 and 2 October 2015. On 6 October 2015 a security advisory and fixes for the issues were released.

The relevant bits from the ChangeLog are:

   * Added fix for CVE-2015-5291 to prevent heap corruption due to buffer
     overflow of the hostname or session ticket. Found by Guido Vranken,
   * Fix potential double-free if mbedtls_ssl_set_hs_psk() is called more than
     once in the same handhake and mbedtls_ssl_conf_psk() was used.
     Found and patch provided by Guido Vranken, Intelworks. Cannot be forced
   * Fix stack buffer overflow in pkcs12 decryption (used by
     mbedtls_pk_parse_key(file)() when the password is > 129 bytes.
     Found by Guido Vranken, Intelworks. Not triggerable remotely.
   * Fix potential buffer overflow in mbedtls_mpi_read_string().
     Found by Guido Vranken, Intelworks. Not exploitable remotely in the context
     of TLS, but might be in other uses. On 32 bit machines, requires reading a
     string of close to or larger than 1GB to exploit; on 64 bit machines, would
     require reading a string of close to or larger than 2^62 bytes.
   * Fix potential random memory allocation in mbedtls_pem_read_buffer()
     on crafted PEM input data. Found and fix provided by Guido Vranken,
     Intelworks. Not triggerable remotely in TLS. Triggerable remotely if you
     accept PEM data from an untrusted source.
   * Fix possible heap buffer overflow in base64_encoded() when the input
     buffer is 512MB or larger on 32-bit platforms. Found by Guido Vranken,
     Intelworks. Not trigerrable remotely in TLS.
   * Fix potential double-free if mbedtls_conf_psk() is called repeatedly on
     the same mbedtls_ssl_config object and memory allocation fails. Found by
     Guido Vranken, Intelworks. Cannot be forced remotely.
   * Fix potential heap buffer overflow in servers that perform client
     authentication against a crafted CA cert. Cannot be triggered remotely
     unless you allow third parties to pick trust CAs for client auth.
     Found by Guido Vranken, Intelworks.

The mbed TLS team was swift to respond to all my reports and inquiries. While 8 vulnerabilities found within a timespan of approximately 1 month is a relatively large amount, these were discovered in part thanks to the library’s very clean and consistent coding style. I relied almost entirely on manual code inspection, and the clean, well-formatted code enabled me to focus on the dissection of the routines’ logic rather than attempt to unmangle labyrinthine constructs and behemoths of code reminiscent of a certain pasta, as has been my experience with some other (high profile) open source projects that I have reviewed.

Throughout my endeavour I employed American Fuzzy Lop in several configurations, none of which yielded any useful results. While AFL is an excellent means to certain ends, this goes to show once more that fuzzing is not a silver bullet for asserting an application’s security.

Interesting to note is that the Dutch secret service (AIVD) commissioned security company Fox-IT to review the OpenVPN+PolarSSL source code and to modify it where appropriate to make it suitable for governmental use, the result of which is OpenVPN-NL, “a hardened version of OpenVPN that includes as many of the security measures required to operate in a classified environment as possible“.

The altered version of PolarSSL, included as the TLS stack of this package, is stripped of various chunks of code that were apparently deemed unnecessary for the application’s purpose, or perhaps regarded as insecure. Other parts were left in, some of which seem to be identical to vulnerable code which I have laid bare in the official releases of mbed TLS / PolarSSL. An example of this is the overflow of the unipwd[] buffer in pkcs12_pbe_derive_key_iv() (in pkcs12.c) if too large a password is passed to it.

I have only reviewed Fox-IT’s PolarSSL code superficially and didn’t make an effort to verify these perceived weaknesses by constructing a proof of concept. However, I intend to do so in the near future.

It is interesting that sometimes a positive consensus is attained regarding a product’s security merely through the propagation of others’ opinions about it. In effect, such a consensus is established upon a network of self-referential ideas that is ultimately not grounded in actual proof.

Open source software has usually been regarded as being quite secure ever since the formulation of Linus’ Law. However, fiascos such as Heartbleed and Shellshock were a rude awakening to the fact that there were no, or far too few, eyeballs; that there were plenty of eyeballs had hitherto been generally accepted as a given.

And despite a formal source code audit of TrueCrypt, vulnerabilities were found by researchers audacious enough to call into question the auditors’ claims.

Similarly, PolarSSL has long been regarded as being secure. Prior to the supposed source code audit by Fox-IT and a formal verification, such a view of the software was largely self-referential and was not grounded in tangible proof. The notion was essentially conceived through inductive reasoning of sorts: PolarSSL’s history of security vulnerabilities has remained fairly succinct since the project’s inception; thus—people must have reasoned—PolarSSL is quite secure. Those weaknesses in PolarSSL which I have identified belie claims of its sound security grounded in the methodical efforts of the audit and the formal verification.

Of the efforts of the audit and verification I speak with some reservation. I am not entirely sure if these efforts expressly covered the vulnerable parts of the library. Either way, bold conclusions made by auditors about TrueCrypt, PolarSSL or other software sustain and validate prevailing ideas regarding the security of such software whilst contradicting the ineluctable truth, which is that the applications can still harbour vulnerable code. It must thus be concluded that any effort, methodical and formal or not, to verify security is susceptible to human error and accidental omission, and should not be taken for granted especially if the stakes are high.

Finally, I would like to underscore the fact that PolarSSL most likely is quite secure compared to complex alternatives such as OpenSSL. It might not be immune to attacks, but claims of immunity or perfection can be attributed only to the most trivial do-nothing one-liners of software. It would be unscrupulous to judge the whole library negatively because of the defects which have been here identified, for they were not discovered in spite of its rigidly clean code and its consistent adherence to conventions. Rather, because of its cleanliness and consistency, such defects were detectable sooner rather than later.