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: David A. Wagner (dawcs.berkeley.edu)
Date: Thu Apr 27 2000 - 13:06:44 CDT


In article <39086AB9.24CB807wirex.com>,
Crispin Cowan <crispinwirex.com> wrote:
> If you use a base+bounds notation, then it is easy to
> create library functions that CORRECTLY do bounds checking on the size of the
> destination buffer, because the size of the buffer is encoded in the string
> object. With the null terminated idiom, the code has no easy way to
> determine the size of the receiving buffer, which is what makes doing
> correct bounds checking in C programs hard.

I'm probably misunderstanding you, but the above looks like it
is confusing two orthogonal notions: the /length/ of a string
(how far until you see the '\0'-terminator), and the /size/ of
the buffer it is stored in (how many bytes have been allocated
for this stringbuffer).

To keep these two notions straight, I'll try to use the terms
/length/ and /size/ consistently. I realize I'm re-using some
terms here, and I hope this won't cause any confusion.

The point is that nul termination is not the problem; the problem
seems to be that C stringbuffers do not store their allocated
/size/ in any place where it can be conveniently accessed for
bounds-checking purposes. Fixing this requires either compiler
modifications or changes to the libc string API.

Do you agree, or am I missing something?

-- David

P.S. In case the above was unclear, here is some more detail
on my reasoning. One may continue to count the /length/ by
scanning for the first '\0'-terminator, as is currently done
with libc's strings API. But to check bounds, we must also
know the /size/ of the destination stringbuffer, and there is
no way to know that unless this /size/ has been stored somewhere
accessible.

Thus, the natural implementation of safe strings would include
a /size/ along with each string buffer; 'strcpy(dst,src)'
(or its analog) could perhaps be implemented by something like
   typedef struct { int size; char *data; } safestring;
   safestring safestrcpy(safestring dst, safestring src) {
     if (strlen(src) >= dst.size)
       return FAILED;
     memcpy(dst.data, src.data, strlen(src)+1);
     return dst;
   }
Note that the above implementation allows for nul-terminated but
safely bounds-checked strings. (Please excuse any bugs in the
above; I hope you will get the idea anyway.)

If you want to allow the programmer to use pointers into the
middle of a stringbuffer, things get more complicated (there
are solutions, but they become more pervasive).