[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Fedora-tools-list] Expermental glibc/gcc4 rpms with buffer overflow protection



Hi!

ftp://people.redhat.com/jakub/chk/
contains experimental gcc4 and glibc rpms providing lightweight buffer
overflow protection to some memory and string functions.

I'm well aware of mudflap, but it has too big runtime overhead
to be used by all programs.  The intent of these changes
is to add some checks that have no or non-measurable
runtime overhead, so something that can be enabled for
all programs and libraries in an operating system.

The changes certainly doesn't prevent all buffer overflows,
but should prevent many common ones.
It works by computing a constant (conservative) number
of bytes remaining to the end of object(s) each destination
pointer passed to memory and string functions points to.
If possible it checks for overflows at compile time,
if not possible passes that constant size to special
checking alternatives of the memory/string functions.

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.
Buffer overflows can be detected at compile time
or at runtime, if the compiler can detect they will not
happen, normal functions as opposed to their checking
alternatives are used.

Below are four different cases that can happen:

char buf[5];
/* 1) Known correct.
      No runtime checking is needed, memcpy/strcpy
      functions are called (or their equivalents inline).  */
memcpy (buf, foo, 5);
strcpy (buf, "abcd");
/* 2) Not known if correct, but checkable at runtime.
      The compiler knows the number of bytes remaining in object,
      but doesn't know the length of the actual copy that will happen.
      Alternative functions __memcpy_chk or __strcpy_chk are used in
      this case that check whether buffer overflow happened.  If buffer
      overflow is detected, __chk_fail () is called (the normal action
      is to abort () the application, perhaps by writing some message
      to stderr.  */
memcpy (buf, foo, n);
strcpy (buf, bar);
/* 3) Known incorrect.
      The compiler can detect buffer overflows at compile
      time.  It issues warnings and calls the checking alternatives
      at runtime.  */
memcpy (buf, foo, 6);
strcpy (buf, "abcde");
/* 4) Not known if correct, not checkable at runtime.
      The compiler doesn't know the buffer size, no checking
      is done.  Overflows will go undetected in these cases.  */
memcpy (p, q, n);
strcpy (p, q);

In the current implementation mem{cpy,pcpy,move,set},
st{r,p,nc}py, str{,n}cat, {,v}s{,n}printf and gets functions
are checked this way.
The diffence 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.

ATM the checking functions are used for C code only, though
libstdc++-v3 header changes to make C++ code protected shouldn't be
that hard.

Please give it a shot on your favourite apps and let us know
if you find any problems with the glibc/gcc4 patches
(please note that gcc4 is not super-stable yet, so if it
issues an internal compiler error, please check the normal rawhide
gcc4 first if the problem is specific to the patched gcc4 or
common with stock gcc4) or what buffer overflows in applications
it detects (both at compile time and at runtime).

	Jakub


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]