Live data from Hacker News

Heap Overflow in Floating Point Parsing (CVE-2013-4164)

ruby-lang.org

11–18 of 18 posts

Re: Heap Overflow in Floating Point Parsing (CVE-2013-4164)

#11
post #10
post #7

Earlier quoted context omitted.

> "more or less" ... on 6 Oct 2011. They announced their plan. It was perfectly reasonable, and Ruby 1.9 was available way before that (2007) and at that time 1.9.3 was around the corner, so the clock was obviously ticking way before this announcement. Ubuntu (and Debian) choses to stick on versions with releases, and maintain security as backported patches if need be, so the onus is now on them to secure their syste…

> Ubuntu (and Debian) choses to stick on versions with releases It's not as simple as just choosing. Every single package that depends on ruby 1.8 needs to move on before ruby 1.8 can itself be removed from the Debian or Ubuntu repositories. Either that, or the decision has to be made for laggard dependent packages to be removed. This takes time. In Ubuntu, ruby1.8 is in main, which means that the Ubuntu Security Tea…

> It's not as simple as just choosing. Every single package that depends on ruby 1.8

It is a matter of choosing, although that choice obviously goes beyond "hey let's bump the version of that lonely package". The choice I refer to is holistic, and also covers how many packages a distribution choses to make depend on ruby, such as the decision to package gems, with overarching (positive and negative) consequences.

Re: Heap Overflow in Floating Point Parsing (CVE-2013-4164)

#12
post #11
post #10

Earlier quoted context omitted.

> Ubuntu (and Debian) choses to stick on versions with releases It's not as simple as just choosing. Every single package that depends on ruby 1.8 needs to move on before ruby 1.8 can itself be removed from the Debian or Ubuntu repositories. Either that, or the decision has to be made for laggard dependent packages to be removed. This takes time. In Ubuntu, ruby1.8 is in main, which means that the Ubuntu Security Tea…

> It's not as simple as just choosing. Every single package that depends on ruby 1.8 It is a matter of choosing, although that choice obviously goes beyond "hey let's bump the version of that lonely package" . The choice I refer to is holistic, and also covers how many packages a distribution choses to make depend on ruby, such as the decision to package gems, with overarching (positive and negative) consequences.

That is the cost of being able to "apt-get install " without having to learn details of the packaging system that yet another language community expects everyone to learn and use, for each that one wants to install.

Remember that dependencies go in multiple directions. Ruby is not necessarily at the top of the stack. I might, for example, want to deploy my Python application stack with puppet. Which requires Ruby.

If the choice is "don't use a distribution", then have fun with that. If the choice is "use a distribution, but don't use it for my stuff", then what makes you so special, and how does this scale to every community that wants the same thing?

Re: Heap Overflow in Floating Point Parsing (CVE-2013-4164)

#13
post #5

Earlier quoted context omitted.

I can read too, announced here https://www.ruby-lang.org/en/news/2011/10/06/plans-for-1-8-7... . However I do think discontinuing security updates after 2 years announcement for a product that even they say is "more or less" used by everyone isn't the best decision.

Conversely, by not giving a shut off date, you get into the same situation Microsoft is in with Windows, where they have to support XP after over a decade. Supporting old software costs money, even if it is an open source project. You've had two years to work on a migration path, what were you doing in the interim?

> Conversely, by not giving a shut off date, you get into the same situation Microsoft is in with Windows, where they have to support XP after over a decade

Microsoft does give end of support dates[0], merely awfully long ones, the calculation of which has been streamlined (something like min(10 years after first release, 2 years after last SP)). XP is in "Extended Support" phase (i.e security updates only), which ends in Apr 2014.

And don't get me started on the "Components of the Major Product" scheme for IE[1] which is downright byzantine.

[0]: http://support.microsoft.com/lifecycle/?ln=en-gb&c2=1173

[1]: http://support.microsoft.com/lifecycle/search/default.aspx?s...

Re: Heap Overflow in Floating Point Parsing (CVE-2013-4164)

#14
In case you're curious about exploitability for code execution... the bug is that this array (Kmax = 16):

    static Bigint *freelist[Kmax+1];
which is indexed by the log2 of the size of the bigint, is not checked:

    static Bigint *
    Balloc(int k)
    {
        [...]
        if ((rv = freelist[k]) != 0) {
            freelist[k] = rv->next;
        }
If it's 0, then the allocation is done safely.

Where does Balloc get called? First with an estimate of the size required for the whole thing, from two locations, then with steadily increasing values starting from 1, from the mult function. With the first allocation we can theoretically perform a complicated operation (a good thing when ASLR is involved) to any location in ruby's bss section after freelist, but every increase requires doubling the size of the input string, and 16 already requires a 300k string, so going more than a few notches forward is impractical. With the second, I think k=16 is guaranteed to get a hit, because the next variable after freelist in the code is:

    static Bigint *p5s;
On my system, and probably on all, this duly shows up immediately afterwards in the binary, and p5s is set before the allocation, so it's not null. The code ends up "allocating" p5s and copying 64k of arbitrary data into p5s->x, which comes from the 'private_mem' static array, also in the bss section. Although this is certainly dangerous, on the 3 systems I tried (OS X, 64-bit Linux, 32-bit Linux), there was much less than 64k of memory in the segment after the array and something read-only immediately followed, so it was guaranteed to crash before anything interesting could happen. It could be possible to exploit anyway if another C thread were accessing the data (not sure if mri ever does this), but the timing would be extremely difficult.

So I suspect that on most systems, this is purely a DOS, even though it involves an overwrite of arbitrary data. However, I could definitely be missing something, as the code is fairly complicated.

Re: Heap Overflow in Floating Point Parsing (CVE-2013-4164)

#15
post #8
post #4

It seems to be a fairly simple patch for 1.8 series, too: https://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/43776 just a few lines truncating input in util.c. Break your ruby here: JSON.parse("[1."+"1"*300000+"]")

update: I just tested this; if you're on 1.8.7, you can manually apply the patch I linked in the parent comment and recompile. There is nothing preventing a backport.

There's also a commit right after the merge commit to change

  if (nf > DBL_DIG * 2) continue;
to

  if (nf > DBL_DIG * 4) continue;

Re: Heap Overflow in Floating Point Parsing (CVE-2013-4164)

#16
So, why does ruby has its own version of strtod? From the comment in https://bugs.ruby-lang.org/projects/ruby-193/repository/revi... ("strtod for IEEE-, VAX-, and IBM-arithmetic machines.") it does not appear to be for machines that don't have it in their C library.

Is it because of the incompatibility between C90 and C99 described in http://www.lehman.cuny.edu/cgi-bin/man-cgi?strtod+3, or don't they trust strtod to return the same results on each system? If so, where does not trusting one's environment end?

Re: Heap Overflow in Floating Point Parsing (CVE-2013-4164)

#17
post #2

Strikes me as a bit silly not to patch this in 1.8 considering it's still fairly widely used and even the default for Ubuntu 12.04 LTS.

I'd much prefer the Ruby team to use their resources for the current versions of Ruby. If the Ubuntu team (or you) are concerned about 1.8 - patch it yourself.
Post reply on HN