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

Luis Javier Merino ljmerino at gmail.com
Thu Sep 27 22:50:37 CEST 2007


> 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.

> 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.

> 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?
>

A custom one, like the ones on Postfix and Qmail.

Actually the reason to avoid pushing strl* is to avoid people thinking
they solve all problems with strings, they don't. If there was any
standard for dynamic strings I'd guess noone would oppose strl* meme
propagation.

For the record, I'm not pushing for bare memcpy, I'm pushing for
dynamic strings. Something internally similar to the following, but
with a sane API:

BEWARE, UGLIEST API EVER FOLLOWS:


#define GROW_SIZE       1000
static void grow(char **dst, int *size, int *nsize, char *src, int slen)
{
        if (*size == 0) {
                *nsize = ((slen + GROW_SIZE) / GROW_SIZE) * GROW_SIZE;
                *dst = (char *) malloc(*nsize);
                if (*dst == NULL)
                        return;
                *size = 1;
        } else {
                if ((*size + slen) > *nsize) {
                        *nsize = ((*size + slen + GROW_SIZE - 1) /
GROW_SIZE) * GROW_SIZE;
                        *dst = (char *) realloc(*dst, *nsize);
                        if (*dst == NULL)
                                return;
                }
        }

        strcpy(*dst + *size - 1, src);
        *size += slen;
}



More information about the dslinux-devel mailing list