Add ~40 index terms to this chapter. A couple of minor tweaks to

doc.docbook.mk are needed for this to work with GEN_INDEX defined but
that will be committed soon enough.

Reviewed by:	-doc (months ago)
This commit is contained in:
Murray Stokely 2001-05-17 01:03:07 +00:00
parent 6296820335
commit acd6619ae0
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=9451
2 changed files with 214 additions and 2 deletions
en_US.ISO8859-1/books/developers-handbook/secure
en_US.ISO_8859-1/books/developers-handbook/secure

View file

@ -1,7 +1,7 @@
<!--
The FreeBSD Documentation Project
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/secure/chapter.sgml,v 1.3 2001/04/18 19:33:27 dd Exp $
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/secure/chapter.sgml,v 1.4 2001/05/14 03:15:19 murray Exp $
-->
<chapter id="secure">
@ -40,26 +40,61 @@
<para>Buffer Overflows have been around since the very
beginnings of the Von-Neuman <xref linkend="COD"> architecture.
<indexterm><primary>buffer overflow</primary></indexterm>
<indexterm><primary>Von-Neuman</primary></indexterm>
They first gained widespread notoriety in 1988 with the Morris
Internet worm. Unfortunately, the same basic attack remains
<indexterm><primary>Morris Internet worm</primary></indexterm>
effective today. Of the 17 CERT security advisories of 1999, 10
<indexterm>
<primary>CERT</primary><secondary>security advisories</secondary>
</indexterm>
of them were directly caused by buffer-overflow software bugs.
By far the most common type of buffer overflow attack is based
on corrupting the stack.</para>
<indexterm><primary>stack</primary></indexterm>
<indexterm><primary>arguments</primary></indexterm>
<para>Most modern computer systems use a stack to pass arguments
to procedures and to store local variables. A stack is a last
in first out (LIFO) buffer in the high memory area of a process
image. When a program invokes a function a new "stack frame" is
<indexterm><primary>LIFO</primary></indexterm>
<indexterm>
<primary>process image</primary>
<secondary>stack pointer</secondary>
</indexterm>
created. This stack frame consists of the arguments passed to
the function as well as a dynamic amount of local variable
space. The "stack pointer" is a register that holds the current
<indexterm><primary>stack frame</primary></indexterm>
<indexterm><primary>stack pointer</primary></indexterm>
location of the top of the stack. Since this value is
constantly changing as new values are pushed onto the top of the
stack, many implementations also provide a "frame pointer" that
is located near the beginning of a stack frame so that local
variables can more easily be addressed relative to this
value. <xref linkend="COD"> The return address for function
<indexterm><primary>frame pointer</primary></indexterm>
<indexterm>
<primary>process image</primary>
<secondary>frame pointer</secondary>
</indexterm>
<indexterm><primary>return address</primary></indexterm>
<indexterm><primary>stack-overflow</primary></indexterm>
calls is also stored on the stack, and this is the cause of
stack-overflow exploits since overflowing a local variable in a
function can overwrite the return address of that function,
@ -157,12 +192,25 @@ int main() {
stack-overflows is to always use length restricted memory and
string copy functions. <function>strncpy</function> and
<function>strncat</function> are part of the standard C library.
<indexterm>
<primary>string copy functions</primary>
<secondary>strncpy</secondary>
</indexterm>
<indexterm>
<primary>string copy functions</primary>
<secondary>strncat</secondary>
</indexterm>
These functions accept a length value as a parameter which
should be no larger than the size of the destination buffer.
These functions will then copy up to `length' bytes from the
source to the destination. However there are a number of
problems with these functions. Neither function guarantees NUL
termination if the size of the input buffer is as large as the
<indexterm><primary>NUL termination</primary></indexterm>
destination. The length parameter is also used inconsistently
between strncpy and strncat so it is easy for programmers to get
confused as to their proper usage. There is also a significant
@ -172,6 +220,9 @@ int main() {
specified.</para>
<para>In OpenBSD, another memory copy implementation has been
<indexterm><primary>OpenBSD</primary></indexterm>
created to get around these problem. The
<function>strlcpy</function> and <function>strlcat</function>
functions guarantee that they will always null terminate the
@ -181,8 +232,21 @@ int main() {
<function>strlcat</function> instructions have been in FreeBSD
since 3.5.</para>
<indexterm>
<primary>string copy functions</primary>
<secondary>strlcpy</secondary>
</indexterm>
<indexterm>
<primary>string copy functions</primary>
<secondary>strlcat</secondary>
</indexterm>
<sect3><title>Compiler based run-time bounds checking</title>
<indexterm><primary>bounds checking</primary>
<secondary>compiler-based</secondary></indexterm>
<para>Unfortunately there is still a very large assortment of
code in public use which blindly copies memory around without
using any of the bounded copy routines we just discussed.
@ -190,6 +254,9 @@ int main() {
add-ons and libraries exist to do Run-time bounds checking in
C/C++.</para>
<indexterm><primary>StackGuard</primary></indexterm>
<indexterm><primary>gcc</primary></indexterm>
<para>StackGuard is one such add-on that is implemented as a
small patch to the gcc code generator. From the StackGuard
website, http://immunix.org/stackguard.html :
@ -212,6 +279,8 @@ int main() {
returns."</para></blockquote>
</para>
<indexterm><primary>buffer overflow</primary></indexterm>
<para>Recompiling your application with StackGuard is an
effective means of stopping most buffer-overflow attacks, but
it can still be compromised.</para>
@ -220,6 +289,11 @@ int main() {
<sect3><title>Library based run-time bounds checking</title>
<indexterm>
<primary>bounds checking</primary>
<secondary>library-based</secondary>
</indexterm>
<para>Compiler-based mechanisms are completely useless for
binary-only software for which you cannot recompile. For
these situations there are a number of libraries which
@ -248,12 +322,23 @@ int main() {
<sect1><title>SetUID issues</title>
<indexterm><primary>seteuid</primary></indexterm>
<para>There are at least 6 different IDs associated with any
given process. Because of this you have to be very careful with
the access that your process has at any given time. In
particular, all seteuid applications should give up their
privileges as soon as it is no longer required.</para>
<indexterm>
<primary>user IDs</primary>
<secondary>real user ID</secondary>
</indexterm>
<indexterm>
<primary>user IDs</primary>
<secondary>effective user ID</secondary>
</indexterm>
<para>The real user ID can only be changed by a superuser
process. The <application>login</application> program sets this
when a user initially logs in and it is seldom changed.</para>
@ -270,6 +355,8 @@ int main() {
<sect1 id="chroot"><title>Limiting your program's environment</title>
<indexterm><primary>chroot()</primary></indexterm>
<para>The traditional method of restricting access to a process
is with the <function>chroot()</function> system call. This
system call changes the root directory from which all other
@ -297,6 +384,8 @@ int main() {
<sect2><title>FreeBSD's jail functionality</title>
<indexterm><primary>jail</primary></indexterm>
<para>The concept of a Jail extends upon the
<function>chroot()</function> by limiting the powers of the
superuser to create a true `virtual server'. Once a prison is
@ -344,6 +433,9 @@ int main() {
<sect2><title>POSIX.1e Process Capabilities</title>
<indexterm><primary>POSIX.1e Process Capabilities</primary></indexterm>
<indexterm><primary>TrustedBSD</primary></indexterm>
<para>Posix has released a working draft that adds event
auditing, access control lists, fine grained privileges,
information labeling, and mandatory access control.</para>
@ -364,6 +456,9 @@ int main() {
resources, IPC, mmaps, the file system working directory, file
descriptors, the # of open files, etc.</para>
<indexterm><primary>positive filtering</primary></indexterm>
<indexterm><primary>data validation</primary></indexterm>
<para>You should never assume that you can catch all forms of
invalid input that a user might supply. Instead, your
application should use positive filtering to only allow a
@ -373,6 +468,8 @@ int main() {
extra careful about paths ("../", "/"), symbolic links, and
shell escape characters.</para>
<indexterm><primary>Perl Taint mode</primary></indexterm>
<para>Perl has a really cool feature called "Taint" mode which
can be used to prevent scripts for using data derived outside
the program in an unsafe way. This mode will check command line
@ -390,6 +487,15 @@ int main() {
other words, a programmer incorrectly assumed that a particular
event would always happen before another.</para>
<indexterm><primary>race conditions</primary>
<secondary>signals</secondary></indexterm>
<indexterm><primary>race conditions</primary>
<secondary>access checks</secondary></indexterm>
<indexterm><primary>race conditions</primary>
<secondary>file opens</secondary></indexterm>
<para>Some of the common causes of race conditions are signals,
access checks, and file opens. Signals are asynchronous events
by nature so special care must be taken in dealing with them.

View file

@ -1,7 +1,7 @@
<!--
The FreeBSD Documentation Project
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/secure/chapter.sgml,v 1.3 2001/04/18 19:33:27 dd Exp $
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/secure/chapter.sgml,v 1.4 2001/05/14 03:15:19 murray Exp $
-->
<chapter id="secure">
@ -40,26 +40,61 @@
<para>Buffer Overflows have been around since the very
beginnings of the Von-Neuman <xref linkend="COD"> architecture.
<indexterm><primary>buffer overflow</primary></indexterm>
<indexterm><primary>Von-Neuman</primary></indexterm>
They first gained widespread notoriety in 1988 with the Morris
Internet worm. Unfortunately, the same basic attack remains
<indexterm><primary>Morris Internet worm</primary></indexterm>
effective today. Of the 17 CERT security advisories of 1999, 10
<indexterm>
<primary>CERT</primary><secondary>security advisories</secondary>
</indexterm>
of them were directly caused by buffer-overflow software bugs.
By far the most common type of buffer overflow attack is based
on corrupting the stack.</para>
<indexterm><primary>stack</primary></indexterm>
<indexterm><primary>arguments</primary></indexterm>
<para>Most modern computer systems use a stack to pass arguments
to procedures and to store local variables. A stack is a last
in first out (LIFO) buffer in the high memory area of a process
image. When a program invokes a function a new "stack frame" is
<indexterm><primary>LIFO</primary></indexterm>
<indexterm>
<primary>process image</primary>
<secondary>stack pointer</secondary>
</indexterm>
created. This stack frame consists of the arguments passed to
the function as well as a dynamic amount of local variable
space. The "stack pointer" is a register that holds the current
<indexterm><primary>stack frame</primary></indexterm>
<indexterm><primary>stack pointer</primary></indexterm>
location of the top of the stack. Since this value is
constantly changing as new values are pushed onto the top of the
stack, many implementations also provide a "frame pointer" that
is located near the beginning of a stack frame so that local
variables can more easily be addressed relative to this
value. <xref linkend="COD"> The return address for function
<indexterm><primary>frame pointer</primary></indexterm>
<indexterm>
<primary>process image</primary>
<secondary>frame pointer</secondary>
</indexterm>
<indexterm><primary>return address</primary></indexterm>
<indexterm><primary>stack-overflow</primary></indexterm>
calls is also stored on the stack, and this is the cause of
stack-overflow exploits since overflowing a local variable in a
function can overwrite the return address of that function,
@ -157,12 +192,25 @@ int main() {
stack-overflows is to always use length restricted memory and
string copy functions. <function>strncpy</function> and
<function>strncat</function> are part of the standard C library.
<indexterm>
<primary>string copy functions</primary>
<secondary>strncpy</secondary>
</indexterm>
<indexterm>
<primary>string copy functions</primary>
<secondary>strncat</secondary>
</indexterm>
These functions accept a length value as a parameter which
should be no larger than the size of the destination buffer.
These functions will then copy up to `length' bytes from the
source to the destination. However there are a number of
problems with these functions. Neither function guarantees NUL
termination if the size of the input buffer is as large as the
<indexterm><primary>NUL termination</primary></indexterm>
destination. The length parameter is also used inconsistently
between strncpy and strncat so it is easy for programmers to get
confused as to their proper usage. There is also a significant
@ -172,6 +220,9 @@ int main() {
specified.</para>
<para>In OpenBSD, another memory copy implementation has been
<indexterm><primary>OpenBSD</primary></indexterm>
created to get around these problem. The
<function>strlcpy</function> and <function>strlcat</function>
functions guarantee that they will always null terminate the
@ -181,8 +232,21 @@ int main() {
<function>strlcat</function> instructions have been in FreeBSD
since 3.5.</para>
<indexterm>
<primary>string copy functions</primary>
<secondary>strlcpy</secondary>
</indexterm>
<indexterm>
<primary>string copy functions</primary>
<secondary>strlcat</secondary>
</indexterm>
<sect3><title>Compiler based run-time bounds checking</title>
<indexterm><primary>bounds checking</primary>
<secondary>compiler-based</secondary></indexterm>
<para>Unfortunately there is still a very large assortment of
code in public use which blindly copies memory around without
using any of the bounded copy routines we just discussed.
@ -190,6 +254,9 @@ int main() {
add-ons and libraries exist to do Run-time bounds checking in
C/C++.</para>
<indexterm><primary>StackGuard</primary></indexterm>
<indexterm><primary>gcc</primary></indexterm>
<para>StackGuard is one such add-on that is implemented as a
small patch to the gcc code generator. From the StackGuard
website, http://immunix.org/stackguard.html :
@ -212,6 +279,8 @@ int main() {
returns."</para></blockquote>
</para>
<indexterm><primary>buffer overflow</primary></indexterm>
<para>Recompiling your application with StackGuard is an
effective means of stopping most buffer-overflow attacks, but
it can still be compromised.</para>
@ -220,6 +289,11 @@ int main() {
<sect3><title>Library based run-time bounds checking</title>
<indexterm>
<primary>bounds checking</primary>
<secondary>library-based</secondary>
</indexterm>
<para>Compiler-based mechanisms are completely useless for
binary-only software for which you cannot recompile. For
these situations there are a number of libraries which
@ -248,12 +322,23 @@ int main() {
<sect1><title>SetUID issues</title>
<indexterm><primary>seteuid</primary></indexterm>
<para>There are at least 6 different IDs associated with any
given process. Because of this you have to be very careful with
the access that your process has at any given time. In
particular, all seteuid applications should give up their
privileges as soon as it is no longer required.</para>
<indexterm>
<primary>user IDs</primary>
<secondary>real user ID</secondary>
</indexterm>
<indexterm>
<primary>user IDs</primary>
<secondary>effective user ID</secondary>
</indexterm>
<para>The real user ID can only be changed by a superuser
process. The <application>login</application> program sets this
when a user initially logs in and it is seldom changed.</para>
@ -270,6 +355,8 @@ int main() {
<sect1 id="chroot"><title>Limiting your program's environment</title>
<indexterm><primary>chroot()</primary></indexterm>
<para>The traditional method of restricting access to a process
is with the <function>chroot()</function> system call. This
system call changes the root directory from which all other
@ -297,6 +384,8 @@ int main() {
<sect2><title>FreeBSD's jail functionality</title>
<indexterm><primary>jail</primary></indexterm>
<para>The concept of a Jail extends upon the
<function>chroot()</function> by limiting the powers of the
superuser to create a true `virtual server'. Once a prison is
@ -344,6 +433,9 @@ int main() {
<sect2><title>POSIX.1e Process Capabilities</title>
<indexterm><primary>POSIX.1e Process Capabilities</primary></indexterm>
<indexterm><primary>TrustedBSD</primary></indexterm>
<para>Posix has released a working draft that adds event
auditing, access control lists, fine grained privileges,
information labeling, and mandatory access control.</para>
@ -364,6 +456,9 @@ int main() {
resources, IPC, mmaps, the file system working directory, file
descriptors, the # of open files, etc.</para>
<indexterm><primary>positive filtering</primary></indexterm>
<indexterm><primary>data validation</primary></indexterm>
<para>You should never assume that you can catch all forms of
invalid input that a user might supply. Instead, your
application should use positive filtering to only allow a
@ -373,6 +468,8 @@ int main() {
extra careful about paths ("../", "/"), symbolic links, and
shell escape characters.</para>
<indexterm><primary>Perl Taint mode</primary></indexterm>
<para>Perl has a really cool feature called "Taint" mode which
can be used to prevent scripts for using data derived outside
the program in an unsafe way. This mode will check command line
@ -390,6 +487,15 @@ int main() {
other words, a programmer incorrectly assumed that a particular
event would always happen before another.</para>
<indexterm><primary>race conditions</primary>
<secondary>signals</secondary></indexterm>
<indexterm><primary>race conditions</primary>
<secondary>access checks</secondary></indexterm>
<indexterm><primary>race conditions</primary>
<secondary>file opens</secondary></indexterm>
<para>Some of the common causes of race conditions are signals,
access checks, and file opens. Signals are asynchronous events
by nature so special care must be taken in dealing with them.