old-www/HOWTO/Secure-Programs-HOWTO/compilation-c.html

256 lines
7.4 KiB
HTML

<HTML
><HEAD
><TITLE
>Compilation Solutions in C/C++</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Secure Programming for Linux and Unix HOWTO"
HREF="index.html"><LINK
REL="UP"
TITLE="Avoid Buffer Overflow"
HREF="buffer-overflow.html"><LINK
REL="PREVIOUS"
TITLE="Library Solutions in C/C++"
HREF="library-c.html"><LINK
REL="NEXT"
TITLE="Other Languages"
HREF="other-languages.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Secure Programming for Linux and Unix HOWTO</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="library-c.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 6. Avoid Buffer Overflow</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="other-languages.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="COMPILATION-C"
></A
>6.3. Compilation Solutions in C/C++</H1
><P
>A completely different approach is to use compilation methods that perform
bounds-checking (see [Sitaker 1999] for a list).
In my opinion, such tools are very useful in having multiple layers of
defense, but it's not wise to use this technique as your sole defense.
There are at least two reasons for this.
First of all, such tools generally only provide a partial defense against
buffer overflows (and the ``complete'' defenses are generally
12-30 times slower); C and C++ were simply not designed to protect
against buffer overflows.
Second of all, for open source programs you cannot be certain what tools
will be used to compile the program; using the default ``normal'' compiler
for a given system might suddenly open security flaws.</P
><P
>One of the more useful tools is ``StackGuard'', a modification of the
standard GNU C compiler gcc.
StackGuard works by inserting a ``guard'' value (called a ``canary'')
in front of the return address; if a buffer overflow
overwrites the return address, the canary's value (hopefully) changes
and the system detects this before using it.
This is quite valuable, but note that this does not protect against
buffer overflows overwriting other values (which they may still be able
to use to attack a system).
There is work to extend StackGuard to be able to add canaries to other
data items, called ``PointGuard''.
PointGuard will automatically protect certain values (e.g., function
pointers and longjump buffers).
However, protecting other variable types using PointGuard
requires specific programmer intervention (the programmer
has to identify which data values must be protected with canaries).
This can be valuable, but it's easy to accidentally omit
protection for a data value you didn't think needed protection -
but needs it anyway.
More information on StackGuard, PointGuard, and other alternatives
is in Cowan [1999].</P
><P
><A
HREF="http://www.trl.ibm.com/projects/security/ssp"
TARGET="_top"
>IBM has developed a stack protection system called ProPolice
based on the ideas of StackGuard</A
>.
IBM doesn't include the ProPolice in its current website - it's just called
a "GCC extension for protecting applications from stack-smashing attacks."
Like StackGuard, ProPolice
is a GCC (Gnu Compiler Collection) extension for
protecting applications from stack-smashing attacks.
Applications written in C are protected by automatically inserting
protection code into an application at compilation time.
ProPolice is slightly different than StackGuard, however, by adding
three features:
(1) reordering local variables to place buffers after pointers
(to avoid the corruption of pointers that could be used
to further corrupt arbitrary memory locations),
(2) copying pointers in function arguments to an area
preceding local variable buffers (to prevent the corruption of pointers
that could be used to further corrupt arbitrary memory locations), and
(3) omitting instrumentation code from some functions
(it basically assumes that only character arrays are dangerous; while
this isn't strictly true, it's mostly true, and as a result ProPolice
has better performance while retaining most of its protective capabilities).
The IBM website includes information for how to build Red Hat Linux and
FreeBSD with this protection;
<A
HREF="http://www.deadly.org/article.php3?sid=20021202175508"
TARGET="_top"
>OpenBSD
has already added ProPolice to their base system</A
>.
I think this is extremely promising, and I hope to see this capability included
in future versions of gcc and used in various distributions.
In fact, I think this kind of capability should be the default -
this would mean that the largest single class of attacks would no longer
enable attackers to take control in most cases.</P
><P
>As a related issue, in Linux you could modify the Linux kernel so that
the stack segment is not executable; such a patch to Linux does exist
(see Solar Designer's patch, which includes this, at
<A
HREF="http://www.openwall.com/linux/"
TARGET="_top"
>http://www.openwall.com/linux/</A
>
However, as of this writing this is not built into the Linux kernel.
Part of the rationale is that this is less protection than it seems;
attackers can simply force the system to call other ``interesting'' locations
already in the program (e.g., in its library, the heap,
or static data segments).
Also, sometimes Linux does require executable code in the stack,
e.g., to implement signals and to implement GCC ``trampolines''.
Solar Designer's patch does handle these cases, but this does
complicate the patch.
Personally, I'd like to see this merged into the main Linux
distribution, since it does make attacks somewhat more difficult and
it defends against a range of existing attacks.
However, I agree with Linus Torvalds and others
that this does not add the amount of protection it would appear to and
can be circumvented with relative ease.
You can read Linus Torvalds' explanation for not including this support at
<A
HREF="http://old.lwn.net/1998/0806/a/linus-noexec.html"
TARGET="_top"
>http://old.lwn.net/1998/0806/a/linus-noexec.html</A
>.&#13;</P
><P
>In short, it's better to work first on developing a correct program
that defends itself against buffer overflows.
Then, after you've done this, by all means use techniques and tools
like StackGuard as an additional safety net.
If you've worked hard to eliminate buffer overflows in the code itself,
then StackGuard (and tools like it) are
are likely to be more effective because there will be
fewer ``chinks in the armor'' that StackGuard will be called on to protect.</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="library-c.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="other-languages.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Library Solutions in C/C++</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="buffer-overflow.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Other Languages</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>