top | item 5129983

(no title)

AngryParsley | 13 years ago

    //C11, safe version of strcat
    errno_t strcat_s(char * restrict s1, 
                     rsize_t s1max, 
                     const char * restrict s2);
strcat_s() copies no more than s1max bytes to s1. The second function, strcpy_s() requires that s1max isn't bigger than the size of s2 in order to prevent an out-of-bounds read:

    //C11, safe version of strcpy
    errno_t strcpy_s(char * restrict s1, 
                     rsize_t s1max, 
                     const char * restrict s2);
Originally, all of the bounds-checking libraries were developed by Microsoft's Visual C++ team. The C11 implementation is similar but not identical.

There are so many problems with this. Yet another slightly different string manipulation function? Why not standardize on one of the already existing ones, such as strlcat/strlcpy? I can see people making some big mistakes with strcat_s, since the size passed is the number of unused characters left in s1, not the size of s1. And strcpy_s can cause a segfault if given an s1max that is greater than the size of s2. Why not only copy up to the first null character?

Also, these functions have the same name as the VC++ functions, but behave differently. In VC++, strcat_s takes the size of s1, not the space remaining. People are going to google for strcat_s, read the MSDN docs, and unknowingly add buffer overflows to their code.

Finally, these functions have annoying behavior. If they hit the limits passed to them, they erase s1. No best-effort. No copy whatever fits. Just destroy the data in the destination string.

strlcat/strlcpy solve all of the problems I've mentioned. See http://www.courtesan.com/todd/papers/strlcpy.html for more info about them. It's sad to see them only supported by *BSD and OS X.

discuss

order

holisd|13 years ago

strlcpy is flawed. And often times silent truncation is not a "best-effort", but a huge hole. This is especially so when strcpy is blindly replaced with strlcpy. For new code, strlcpy is flawed.

to3m|13 years ago

Ulrich Drepper? Is that you?

There are valid reasons not to use strlcpy, but we need something like it. What we do not need is this _s shit, which has all the same problems (which sometimes matter, and sometimes don't) WHILE BEING MASSIVELY HARDER TO USE. And what's the advantage? Just that it returns an errno. That's fine, but what about the rest of it? Just read the instructions for it - it's crap! (I can imagine why they think they want it to work this way, because it gives you a fighting chance again non-0-terminated source strings, but it's just never going to work properly if you've only got one size argument.)

Using strlcpy, by contrast, is simplicity itself.

About 99% of the time when you're using strlcpy (and strlcat), you can just do your calls, passing the same size value into each one (how convenient), then check the length of the result using strlen. Is it one less than the size of the buffer? Yes? Then assume there's an overflow, and disregard the result, assuming you even care about that. This is very straightforward to do, and (unlike this _s junk) doesn't require you to go updating counts or checking maximum values or any of that error-prone nonsense. Just one check at the end, rather than a bunch of updates and stuff scattered all through your string code.

strlcpy! Just say yes!

AngryParsley|13 years ago

It's a very rare situation in which truncation is worse than a buffer overflow. I'd also bet that erasing the destination string is more liable to cause problems than truncating it. For example, the programmer might have pointers to locations in the destination string passed to str*cat. All of a sudden, these pointers are to garbage data.

strlcpy's behavior is the same as snprintf: return what the length would have been if there was enough room. That way one can recover from the error and realloc enough space. C programmers are used to this pattern.

angersock|13 years ago

Why the hell didn't they just pick the existing MSVS semantics? This type of garbage is huge when dealing with cross-platform code, in a number of subtle cases--usually with string manipulation.

cmccabe|13 years ago

Yeah, it's hard to believe that they deliberately picked a syntax that would compile but cause crashes and security issues for the people already using these functions.

At least now we have an ironclad reason not to ever use this garbage.

[edit: I almost wonder if someone on the committee deliberately put this in to sabotage the whole "safe C string functions" farce. Reminds me of a Simpsons episode:

Speaker: Then it is unanimous, we are going to approve the bill to evacuate the town of Springfield in the great state of—

Congressman: Wait a second, I want to tack on a rider to that bill – $30 million of taxpayer money to support the perverted arts.

Speaker: All in favor of the amended Springfield-slash-pervert bill? [entire Congress boos] Bill defeated. [gavel]

http://en.wikiquote.org/wiki/The_Simpsons/Season_6 ]