Tuesday, December 29, 2009

-D_PLZ_UNFORTIFY_MAH_SOURCE_KTHXBYE

More than five years ago Jakub Jelinek implemented object size checking in GCC.  This feature (combined with GLIBC runtime checks) helps to detect many buffer overflows, both compile-time and run-time.  Of course, this brings some limitations to code.

Since then many distibutions (ALT Linux, Gentoo, OpenSUSE, Owl/*/Linux) turned this feature on by default.  But there were those who resisted...

In February, 2007 patch from OpenSUSE was offered to Vim developers.  Almost immediately it was rejected with resolution "The problem is in the compiler, so fix the compiler".

Now to the funny part.


Patch 7.2.044
Problem:    Crash because of STRCPY() being over protective of the destination
   size. (Dominique Pelle)
Solution:   Add -D_FORTIFY_SOURCE=1 to CFLAGS.  Use an intermediate variable
   for the pointer to avoid a warning.


Patch 7.2.251 (after 7.2.044)
Problem:    Compiler adds invalid memory bounds check.
Solution:   Remove _FORTIFY_SOURCE=2 from CFLAGS. (Dominique Pelle)


Patch 7.2.316
Problem:    May get multiple _FORTIFY_SOURCE arguments. (Tony Mechelynck)
Solution:   First remove all these arguments and then add the one we want.
   (Dominique Pelle)

I have a great citation for that case - this "won't solve the problem, only create the illusion that it works".

Heavy New Year, everyone, and double-check code that you intend to use in your usual life.

1 comment:

  1. The patch from 2007 was not portable, so it cannot be accepted since Vim needs to compile on all kinds of platforms.

    Ubuntu changed gcc to enable FORTIFY_SOURCE=2. See man gcc on Ubuntu which says:

    ===
    NOTE: In Ubuntu 8.10 and later versions, -D_FORTIFY_SOURCE=2 is set by default, and is activated when -O is set to 2 or higher. This enables additional compile-time and run-time checks for several libc functions. To disable, specify either -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0.
    ===

    Adding extra checks is good, but the problem is that -D_FORTIFY_SOURCE=2 breaks valid C programs.

    See: http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html

    Quoting the relevant part in above link:

    ==
    The intended use in glibc is that by default no protection is done, when the above GCC 4.0+ and -D_FORTIFY_SOURCE=1 is used at optimization level 1 and above, security measures that shouldn't change behaviour of conforming programs are taken. With -D_FORTIFY_SOURCE=2 some more checking is added, but some conforming programs might fail.
    ==

    So to sum up: -D_FORTIFY_SOURCE=1 is fair and adds security (and this is what Vim compiles with), but -D_FORTIFY_SOURCE=2 breaks valid C program (like Vim).

    -- Dominique

    ReplyDelete