Partager via


When adding security bugs to your code is not your fault!

David LeBlanc and I (and a bunch of others) just had a little email exchange about some fascinating integer overflow vulnerabilities in gcc.

Long story made short: the code you add to detect integer overflows might actually be removed by the compiler because of assumptions made by the optimizer. I was going to write a post on the subject, but David did it for me :-) A frankly, no-one knows int-overflow science quite like LeBlanc.

I can't help but be reminded of another compiler optimization vulnerability we discovered a few years back. I wonder what else might be in store for us from the world of compiler optimizations?

Comments

  • Anonymous
    April 04, 2008
    I would say there is a quite a few more of these types of bugs on the way. Compilers are always pushing the optimization edge whenever possible.  So this bug does not surprise me. It just helps to further make the point that binary analysis is extremely important and still relevant. Pure source code analysis will never be enough on compiled languages.

  • Anonymous
    April 05, 2008
    talk to v-fefe about this stuff if you havent already.

  • Anonymous
    April 05, 2008
    I was under the impression that Felix von Leitner tried to get this fixed two years ago. http://gcc.gnu.org/ml/gcc-bugs/2006-04/msg01297.html So why are people only talking about it just now?

  • Anonymous
    April 05, 2008
    ...known issue. See (e.g.): http://gcc.gnu.org/ml/gcc-bugs/2006-04/msg01297.html

  • Anonymous
    April 05, 2008
    ...known issue? See (e.g.): http://gcc.gnu.org/ml/gcc-bugs/2006-04/msg01297.html

  • Anonymous
    April 05, 2008
    It's an old story....look at http://blog.fefe.de/?ts=babc3ebb There it was published in April 2006!

  • Anonymous
    April 05, 2008
    This particular gcc vulnerability has been known for years, and the gcc developers are not very forthcoming in fixing it, claiming that the current gcc behaviour is standards-compliant.

  • Anonymous
    April 06, 2008
    Actually I think this has been know for some time by now. The GCC team said its fixed but it is apparently not fixed... I think they are too slow :/

  • Anonymous
    April 06, 2008
    Yeah, thanks for discovering this "new" bug: http://gcc.gnu.org/ml/gcc-bugs/2006-04/msg01297.html http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27180 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26763 ;-)

  • Anonymous
    April 06, 2008
    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26763

  • Anonymous
    April 06, 2008
    There is nothing to fix in GCC. This isn't a bug in GCC. C isn't assembler and it's not defined by common-sense but an international standard. If you read the C standard, you'll realize that the so-called "security" overflow checks exhibit undefined behaviour. Also the use of "int" and mention of "integer overflow" is really a red herring in the US-CERT publication because that's not the issue at all.

  • Anonymous
    April 07, 2008
    Hi, back in 2003 we found a serious bug in JDK 1.4.2ś System.arraycopy() routine.   Using this routine a few thousand times in one session would break its logic so that only part of the source array would get copied over to the destination array.  Turned out that Hotspotś optimized C++ array copy code was buggy. Once the Hotspot compiler identified this routine as a ¨hotspot" for optimization, it would replace the original code with the optimized, yet buggy, C++ code. Java folks will know that this is one of the core routines in the JDK. When we contacted Sun, they told us not to rely on any claims made by their APIs.

  • Anonymous
    April 07, 2008
    Commenters above: where did you see Howard or David claiming to have discovered that?? Anyway, it is known and not fixed? Even worse.

  • Anonymous
    April 07, 2008
    Kurisu, so how do you propose folks defend against int overflow vulns?

  • Anonymous
    April 08, 2008
    I suggest reading the C standard. Carefully.

  • Anonymous
    April 08, 2008
    Kurisu - so do you know the C spec inside and out? I certainly do not, and I'd consider myself a pretty decent C and C++ coder. If I add defensive code I expect it to stay there!

  • Anonymous
    April 09, 2008
    I use something like this: if ((len < 0) || (len >= size_of_buffer_in_bytes)) { /* overflow */ } And often I spot-check the executable to make sure the check actually works, by intentionally causing an overflow. That verifies the 'if' as well as whatever action is supoose to happen inside the 'if' (That is a basic testing requirement. Never assume the compiler - or anything else - is not buggy!) And yes, that code might be slower than just checking for wraparound. But IMO it has distinct advantages:

  1. it makes clear it is explicitly bounds-checking the len. Less experienced programmers may not understand what "len + buf < buf" means. Or they might cut-and-paste the C code into another language that has different semantics. Sure, it would be great if everyone is skilled. But reality is people are not and many people do not care enough to learn. Security related code by nature is not executed except under unusual circumstances (ie, an attack), so normal testing will not detect the problem.
  2. If the 32-bit code is ported to a world where ints are 64-bit, that wraparound check may not detect an overflow past the end of the code. Howard, you should know that software development is a learning process; now you've learned that compilers optimize away code in ways you didn't expect. Unfortunately, that might mean you have to audit previously written code for that situation (I hope somebody does!). That is no different than what other people have done in response to buggy Windows code; or buggy tools from many vendors; or mitigation for specific attacks.
  • Anonymous
    April 09, 2008
    The comment has been removed
  • Anonymous
    April 09, 2008
    Let me state once more that the issue you're talking about has nothing to do with integer overflows. It's about pointer arithmetic. If mean that the value of "len" is the result of an integer overflow, you're checking in the wrong place anyway. You can't detect an integer overflow after it happened because it causes undefined behaviour. You can at best prevent a buffer overflow (or out-of-bounds read rather) here but only if you do it correctly something the example code clearly doesn't do. The two problems are certainly similar but are technically very different because integer arithmetic and pointer arithmetic follow different rules. You can easily find discussions, tutorials and even C code online explaining how you avoid integer overflows, if you can't or don't want deduce this yourself from the C standard.