OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
Subject: Re: Buffer Overflows and DoS
From: Horst von Brand (vonbrandinf.utfsm.cl)
Date: Thu Apr 27 2000 - 08:09:45 CDT


[Some paragraphs reindented for readablility]
Crispin Cowan <crispinwirex.com> said:
> Horst von Brand wrote:
> > Crispin Cowan <crispinwirex.com> said:
> > > Buffer overflows are largely a result of:
> > > * the C idiom of null-terminated strings
> > I got the same results in FORTRAN and Pascal just by wandering off the end
> > of arrays...

> Sure, but you have to work harder to get those kinds of bugs in
> FORTRASH^H^H N and Pascal. To be really safe, you need a type-safe
> language that does bounds checking. The C null-termination idiom just
> aggrevates the problem.

Harder? No... to exploit them is just as hard with Pascal's "packed array
of char" and C's "char[]" as they are exactly the same thing under the hood.

> Note that Bernstein has also implemented a strings library that dumps the
> C null-termination idiom in favor of a base+bounds idiom. He (correctly)
> feels that this idiom is less vulnerable to potential buffer overflow
> attacks.

For better or worse, C is here to stay. And C doesn't use this natively, so
it is of no much use in the end. Besides, how you keep track of the length
of your strings is irrelevant, you have to check bounds. And that would
mean an extra two words for each and every string (one the length of the
array, another the current length). 8 bytes extra for "foo". No,
thanks. Better use C++ strings then, at least you'd win on some other
fronts too [Ducks and hides from C fanatics].

> > > * the unfortunate coincidence that stacks grow down and strings grow
> > > up

> > It is certainly possible to smash a upward-growing stack. Just use a buffer
> > in one of the functions in the call chain instead of a local buffer.

> Correct. But it's harder to craft such an attack.

No. Functions that are called with a buffer elsewhere as arguments abound.
That such attacks aren't widespread is just result of the fact that
machines with stacks that grow upward aren't that common. Just like attacks
that work even when the stack is not executable aren't common today, but as
such patches for the linux kernel (and similar mechanisms for other OSes)
have been discussed at length, crackers are starting to write them. Just as
Linus predicted...

> > > * the wide spread use of poorly typed languages that don't do strong
> > > array bounds checking

> > Array bounds checking is quite costly (some 3 or 4 extra instructions
> > for the 1 instruction doing the access on the fast path). Most Pascal
> > compilers (the language specifies array bounds checking for each
> > access!) I know had a flag to turn it off, just because of this.

> I agree. That's why we feel that StackGuard has long-term viability.
> Function call returns are far less frequent than array references, so
> StackGuard's overhead will always be lower than bounds checking.

But it only notices that the cage is open when the bird is long gone, so it
isn't a solution for everything. Ideal would be for the compiler (or a
lint-like tool) check array bounds at compile time, and warn each time it
can't prove bounds won't be overrun. But to get the noise level down to
bearable seems to need much more work still. And C's convoluted semantics
and laisez-faire with types certainly doesn't help a bit here.

-- 
Dr. Horst H. von Brand                       mailto:vonbrandinf.utfsm.cl
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513