strl* (was: Re: Advent4 patch, second try)

Stefan Sperling stsp at stsp.name
Thu Sep 27 19:35:17 CEST 2007


On Thu, Sep 27, 2007 at 10:41:34AM +0200, Luis Javier Merino wrote:
> But, strl* functions can truncate data, which sometimes leads to
> buffer overflows,

I don't get this point.

Can you explain to me why truncating strings and ensuring that the
truncated result is null-terminated can lead to buffer overflows?
I've seen Drepper make the same point without explaining why
this could happen.

I can see that it may cause trouble in applications if they
expect certain amounts of data in a string and don't get all data
because the string was truncated. But such apps are likely coded
badly anyway. And you can only DOS them by causing strings to be truncated
to (presumably) make them crash. You cannot run shellcode by exploiting
a buffer overflow anymore. This is a good thing.

Also the return values of strl* tell you whether a string
was truncated or not. So you can easily fix the app to behave properly
if truncation occurs. 

> and are not on any standard, which means you have to
> include your own versions anyway if you intend to support systems like
> cygwin, beos, hpux, irix, etc...

First, just because something is not in a standard does not
imply it's bad. OOXML may still become a standard as well some day,
go figure.

Second, some functions already in glibc are not in any standard either,
While porting a Linux program to *BSD, I had to copy dprintf and vdprintf
from glibc. I was lucky the Linux program I was porting is GPL'd, else
I would have had to rewrite them myself using the man page as a spec
and I would have likely gotten them subtly wrong.

See the dprintf man page:

  These  functions  are  GNU extensions, not in C or POSIX.  Clearly, the
  names were badly chosen.  Many systems (like MacOS)  have  incompatible
  functions called dprintf(), usually some debugging version of printf(),
  
So glibc already contains non-standard functions, and they even chose
names that were already being used somewhere else for something
completely different.

Hence I don't see how the "it's not part of any standard" argument applies.

> Besides, a good API for dynamically allocated buffers is at least as
> easy to use as str* functions.

What API do you mean? memcpy?

memcpy and friends are *not* a good API to handle strings.
These functions are designed to copy data of arbitrary types
from one piece of memory to another. Using them for strings means
you have to watch lots of corner cases yourself to guarantee the
integrity of the data type "string", or else you will likely in
some situations end up with, for example, a non-terminated string.

Creating an interface that is easy to use for a certain
purpose like string handling is a huge gain because many
security bugs in C occur because people often use C library
and other interfaces improperly (for example passing the wrong
size to strncpy). This does not mean that people are stupid.
It's just that in reality people make mistakes all the time.

Stupid interfaces that are cumbersome to use are bound to
cause problems some time or another. And fixing interfaces
is much easier than fixing people to always do the right thing
in 100% of their time spent programming against crappy interfaces.

strl* are designed to fix that - they are really easy to use
and reliable. Check the paper for all the conditions they check,
you really don't want to do all that manually with memcpy:
http://www.openbsd.org/papers/strlcpy-paper.ps

> Of course, strl* are the best choice for fixing buffer overflows.
  
Because that's what they have been designed for.

-- 
stefan
http://stsp.name                                         PGP Key: 0xF59D25F0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mailman.dslinux.in-berlin.de/pipermail/dslinux-devel-dslinux.in-berlin.de/attachments/20070927/1b1cd63e/attachment.pgp 


More information about the dslinux-devel mailing list