difference between gcc -D_FORTIFY_SOURCE=1 and -D_FORTIFY_SOURCE=2

SecurityGccGlibc

Security Problem Overview


Can someone point out the difference between gcc -D_FORTIFY_SOURCE=1 and -D_FORTIFY_SOURCE=2? I guess =2 is more secure? I haven't been able to find a list which lists differences point by point.

I have also read that -D_FORTIFY_SOURCE=2 should be used with -O2, otherwise not all features would be available. Also here i haven't found a list which would specify the regressions in detail. I would especially be interested to compile with -Os as the target is a device with not so much flash memory.

Any hints on where this is documented welcome!

Security Solutions


Solution 1 - Security

From the manual page for the Feature Test Macros (man 7 feature_test_macros)

> ### _FORTIFY_SOURCE (since glibc 2.3.4) > > Defining this macro causes some lightweight checks to be performed to detect some buffer overflow errors when employing various string and memory manipulation functions (for example, memcpy, memset, stpcpy, strcpy, strncpy, strcat, strncat, sprintf, snprintf, vsprintf, vsnprintf, gets, and wide character variants thereof). For some functions, argument consistency is checked; for example, a check is made that open has been supplied with a mode argument when the specified flags include O_CREAT. Not all problems are detected, just some common cases. > > If _FORTIFY_SOURCE is set to 1, with compiler optimization level 1 (gcc -O1) and above, checks that shouldn't change the behavior of conforming programs are performed. > > With _FORTIFY_SOURCE set to 2, some more checking is added, but some conforming programs might fail. > > Some of the checks can be performed at compile time (via macros logic implemented in header files), and result in compiler warnings; other checks take place at run time, and result in a run-time error if the check fails. > > Use of this macro requires compiler support, available with gcc since version 4.0.

Moreover, the article Enhance application security with FORTIFY_SOURCE (March 2014) says:

  • gcc -D_FORTIFY_SOURCE=1 adds checks at compile-time only (some headers are necessary as #include <string.h>)
  • gcc -D_FORTIFY_SOURCE=2 also adds checks at run-time (detected buffer overflow terminates the program)

Essentially, _FORTIFY_SOURCE level 2 is more secure, but is a slightly riskier compilation strategy; if you use it, make sure you have very strong regression tests for your compiled code to prove the compiler hasn't introduced any unexpected behaviour.

Solution 2 - Security

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html goes into more detail than feature_test_macros(7).

Here's the relevant excerpt, lightly edited/reformatted for clarity:

> The difference between -D_FORTIFY_SOURCE=1 and -D_FORTIFY_SOURCE=2 > is e.g. for > > struct S { > struct T { > char buf[5]; > int x; > } t; > char buf[20]; > } var; > > With -D_FORTIFY_SOURCE=1, > > strcpy (&var.t.buf[1], "abcdefg"); > > is not considered an overflow (object is whole var), while > with -D_FORTIFY_SOURCE=2 > > strcpy (&var.t.buf[1], "abcdefg"); > > will be considered a buffer overflow. >
> Another difference is that with -D_FORTIFY_SOURCE=2, %n > in format strings of the most common *printf family functions > is allowed only if it is stored in read-only memory (usually > string literals, gettext's _("%s string %n") is fine too), but > usually when an attacker attempts to exploit a format string > vulnerability, %n will be somewhere where the attacker could > write it into.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFrank Meerk&#246;tterView Question on Stackoverflow
Solution 1 - SecurityColonel PanicView Answer on Stackoverflow
Solution 2 - SecurityjjlinView Answer on Stackoverflow