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

Stefan Sperling stsp at stsp.name
Fri Sep 28 15:55:05 CEST 2007


On Thu, Sep 27, 2007 at 10:50:37PM +0200, Luis Javier Merino wrote:
> > 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.
> 
> Oops, sleep deprivation on my part, I actually meant security
> vulnerabilities, such as when dealing with file paths.

Ooops, I also indirectly misquoted Mr. Drepper there, because
he actually said "security vulnerabilities", not "buffer overflows".
But as I said the fact that he gave no explanation doesn't help his
credibility.

> > 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.
> 
> I see, didn't know it. Shame on me.

This shows you haven't read the paper.

And it would be interesting to know whether Drepper knows this...

> Actually the reason to avoid pushing strl* is to avoid people thinking
> they solve all problems with strings, they don't.

This also shows you haven't read the paper.

strl* don't want to solve all possible string problems.
See the section "What strlcpy() and strlcat() are not" in the paper:
http://www.openbsd.org/papers/strlcpy-paper.ps

strl* want to provide an API for strings in fixed-sized buffers
that, if used, *eliminates* the possibility of buffer overflow attacks. 
(Note: eliminate, not just "make less likely" or something like that.)

> For the record, I'm not pushing for bare memcpy, I'm pushing for
> dynamic strings.

The only main difference between heap and stack allocations is
that one puts the buffer on the stack and the other on the heap.

Buffers on the heap can be larger than buffers on the stack,
and they can dynamically change their size. So you want heap buffers for
strings that you want to grow or shrink dynamically, but using stack
buffers for (relatively) fixed-sized strings is just fine and common
practice.

In many situations, like filenames, the OS imposes limits
on the maximum size of the string anyway, so what's wrong
with "char path[MAXPATHLEN];" ?

The point is that even if you only use dynamically allocated strings,
all you have essentially done is moving your buffers from the
stack into the heap segment. But badly managed heap buffers can be
overflown just as well as badly managed stack buffers, so you still
have the same essential problem.

The fact that heap buffers are a tad harder to exploit than stack
buffers is irrelevant, because heap overflows are a very well
understood problem, too.
Because there is no return address you can overwrite directly on
the heap, you first have to manipulate internal heap management data to
exploit a heap buffer vulnerability. But once you've exploited the
vulnerability you can still write arbitrary values to arbitrary
memory locations, so you can, for example, modify a return address
that sits on the stack. See http://en.wikipedia.org/wiki/Heap_overflow
for links to more detailed explanations.

So moving things onto the heap alone does not solve anything.
You still have to manage your buffers properly anyway.
And this is what strl* do for fixed-sized buffers.
 
> If there was any
> standard for dynamic strings I'd guess noone would oppose strl* meme
> propagation.

But what has an API for dynamic strings got to do with an
API for fixed-sized strings?

I'm not at all against a good standard C API to handle dynamic
strings. That would be great! The same argument about good APIs
I made earlier applies.

glibc does not have an API to properly handle dynamic strings.
Nor do other libc's (*BSD, Solaris, Mac OS X).

But at least with strl* the other libc's I've mentioned have the
equivalent for fixed-sized buffers. Which is far from perfect,
because the overflow problem remains for badly managed heap buffers,
but at least it's a step in the right direction.

I don't understand why some people think this is bad.... :-/
Solving one problem at a time seems to be a reasonable approach to me.

-- 
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/20070928/09321557/attachment.pgp 


More information about the dslinux-devel mailing list