[15914] in bugtraq

home help back first fref pref prev next nref lref last post

Re: StackGuard with ... Re: [Paper] Format bugs.

daemon@ATHENA.MIT.EDU (Alan DeKok)
Sat Jul 22 19:38:09 2000

Message-ID:  <200007221543.LAA04529@cpu1751.adsl.bellglobal.com>
Date:         Sat, 22 Jul 2000 11:43:26 -0400
Reply-To: Alan DeKok <aland@STRIKER.OTTAWA.ON.CA>
From: Alan DeKok <aland@STRIKER.OTTAWA.ON.CA>
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  Your message of "Fri, 21 Jul 2000 15:52:24 MDT." 
              <200007212152.e6LLqPi22099@cvs.openbsd.org>

Theo de Raadt <deraadt@cvs.openbsd.org> wrote:
> Automated tools do not help because you still have to check for the
> last category by hand, so you might as well read everything.

  That's like saying "'Make' doesn't help, because you can always fall
back to 'ls -l' and 'cc ...'"

  Automated tools HELP.  They are not ENOUGH.  I tried to make this
clear in the documentation for my scanner.  An automated scanner can
help to protect you against the obvious security bloopers.

> [ ... ]
> 	hand-made log()-style functions which end up calling v*() functions

  The problem (in the end) is NOT printf and friends, it's <stdarg.h>,
and the va_*() functions.  They can trivially be convinced to walk up
the stack, returning arguments which were not passed to the function.
This is a bug in the C compiler.

  I'm not a compiler expert, nor am I familiar with GCC.  But I would
guess that one solution to these variable argument functions would be
to fix va_start() and friends.  That is, va_arg() should ensure that
it doesn't walk off of the current stack frame.

  In the header files I have for for GCC 2.7.2.3, va_arg() is defined as:

#define va_arg(AP, TYPE)
 (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)),  \
  *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE))))

  This would appear to be the root of the problem.  va_arg() doesn't
do bounds checking.  That's a hell of a security hole, as we've seen
recently.  The user-space/programmer fixes to code are nothing more
than band-aids to work around a security hole in the compiler.

  va_arg() should be a built-in function, which ensures that it
doesn't return more arguments than were passed.  It should be possible
to add these checks to the gcc, as the compiler knows the size of the
current stack frame.

  There's no substitute for fixing the *root* of the problem, to
ensure that mistakes which are easy to make do not have adverse side
effects.

  Alan DeKok.

home help back first fref pref prev next nref lref last post