Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [day] [month] [year] [list]
Date: Sat, 19 Dec 2015 21:45:01 +0000
From: Jo Shields <directhex@...box.org>
To: oss-security@...ts.openwall.com
Subject: CVE-2009-0689 discovered in Mono prior to 4.2

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Dear all,

Security researchers at NCC Group have discovered that CVE-2009-0689, a
definite DOS (and possible arbitrary code execution) in various
applications' string-to-double parser implementations, also applies to
Mono versions prior to 4.2.

A fix is available
at https://gist.github.com/directhex/01e853567fd2cc74ed39 and should
apply cleanly to all versions of Mono you might care about.

This fix should be applied to all Mono packages prior to 4.2 (everything
except Debian Unstable, Ubuntu 16.04, and Arch, from a quick look)

Attached is the disclosure as-received by us, which includes a minimal
test case to demonstrate the vulnerability.

Thanks to Peter McLarnan <Peter.McLarnan@...group.trust> and Andy
Schmitz <andy.schmitz@...group.trust>

Apologies for the lateness in sending this, I sent it to the wrong
list & didn't notice until pointed out to me recently.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAEBCAAGBQJWdc/dAAoJEMkPnLkOH60MQ3kH/3hNr7Fx/XOc+ql1UJ9LwEP0
+oPLCTPOEfG6b448oISDvVhxJaKkCpmMSKHjrcY80ig+dKm7qLp9o3sWRSzBmjA/
lXVIiHeU11KTsAlgMamNminL+kqNm8H7FlEAoqJIudb2pzkfUrEwLya3+rSnZe54
FBt0uGuHx3eF7ms8BTo3vEtQlhMsiYJh78sKCGNUSqLZ5ObGqLXoKiZq/J1JtZ/w
G5kRRD2GpyoIMsaneejBzqH7XF1GTvbSlEiWRScslRAXpj9y59ssHDDHi4FhIrSS
vPn0s+biTS3bsH9/H33uwcDPh65UaNha+J+opKZd5MMUqtoBERs6vHyGpaCNNPI=
=uXMH
-----END PGP SIGNATURE-----

Mono `strtod` Bounds Checking Vulnerability
====

Severity
----
High

Impact
----
An attacker who can cause a carefully-chosen string to be converted to a floating-point number can cause a crash and potentially induce arbitrary code execution.

Details
----

The float-parsing code used in Mono (before 4.2) is derived from classic code written by David M. Gay, and lives in `mono/utils/strtod.c`.

This code has a vulnerability which has been noted before, and fixed in the upstream version, but this fix was apparently not propagated into the Mono codebase. See [1].

The issue concerns the `freelist` array, which is a global array of 16 pointers to `Bigint`. This array is part of a memory allocation and reuse system which attempts to reduce the number of `malloc` and `free` calls. The system allocates blocks in power-of-two sizes, from 2^0 through 2^15, and stores freed blocks of each size in a linked list rooted at the corresponding cell of `freelist`. 

The `Balloc` and `Bfree` functions which operate this system fail to check if the size parameter `k` is within the allocated 0..15 range. As a result, a sufficiently large allocation will have k=16 and treat the word immediately after `freelist` as a pointer to a previously-allocated chunk.

The specific results may vary significantly based on the version, platform, and compiler, since they depend on the layout of variables in memory. However, the worst-case scenario of arbitrary code execution should be assumed until it can be ruled out.

For an example, in a version distributed with Ubuntu 12.04, `freelist[16]` coincides with the variable `p5s`, which stores the number 625 in `Bigint` form. Importantly, this allocation is small. When the code reuses this supposedly-free space and attempts to write a large number, the numeric data overflows the allocation and can affect other parts of the program. By overwriting `malloc` heap metadata, it is likely possible to cause arbitrary code execution, although we do not yet have a full demonstration of this.

The vulnerable code does not appear in version 4.2, which seems to use a different library.


[1]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0689



Reproduction
----

The following C# code suffices to demonstrate the issue on Mac OS X with packaged Mono versions 3.12.1 and 4.0.4:

~~~
using System;
class Test
{
    static void Main()
    {
        string input = "1." + new string('1', 294912);
        Double.Parse(input);
    }
}
~~~

Running the input causes an immediate crash.



Recommendation
----

Implement the checks found in the current version of the upstream software (http://www.netlib.org/fp/dtoa.c):

Balloc
~~~
	if (k <= Kmax && (rv = freelist[k]))
		freelist[k] = rv->next;
    else {
...
~~~

Bfree
~~~
	if (v) {
		if (v->k > Kmax)
#ifdef FREE
			FREE((void*)v);
#else
			free((void*)v);
#endif
		else {
			ACQUIRE_DTOA_LOCK(0);
			v->next = freelist[v->k];
			freelist[v->k] = v;
			FREE_DTOA_LOCK(0);
			}
		}
	}
~~~

Consider a full upgrade, as there may be other relevant bugs in the original version. (See http://www.netlib.org/fp/changes for a rough changelog)

[ CONTENT OF TYPE application/pgp-signature SKIPPED ]

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ