LWN.net Logo

The ups and downs of strlcpy()

The ups and downs of strlcpy()

Posted Jul 19, 2012 15:55 UTC (Thu) by RobSeace (subscriber, #4435)
In reply to: The ups and downs of strlcpy() by wahern
Parent article: The ups and downs of strlcpy()

Indeed, it seems to me the same arguments against strlcpy() could be made against snprintf(), and yet everyone seemed to accept that THAT was clearly worth having as a superior alternative to sprintf()... Maybe it's just some people like "n" and really hate "l"? ;-) Admittedly, I do find the strl*() names rather nonstandard and hard to get used to... But, given than strn*() was already taken, they didn't have much choice, and nothing else would be much of an improvement... Maybe nstrcpy()?


(Log in to post comments)

The ups and downs of strlcpy()

Posted Jul 19, 2012 22:08 UTC (Thu) by nix (subscriber, #2304) [Link]

snprintf() has the advantage that there was no sane way to use sprintf() securely -- you couldn't tell how big a buffer it would need in the general case without reimplementing the guts of sprintf() yourself. You couldn't do it by tracking some extra value, the way you can with string lengths. snprintf() lets you do it with two calls, one with a tiny size, then one with the size returned from the previous call, plus one. Much better.

The ups and downs of strlcpy()

Posted Jul 19, 2012 22:44 UTC (Thu) by RobSeace (subscriber, #4435) [Link]

> snprintf() has the advantage that there was no sane way to use sprintf()
> securely -- you couldn't tell how big a buffer it would need in the
> general case without reimplementing the guts of sprintf() yourself.

I'm not sure how long glibc has had open_memstream(), but you could've done it with that and fprintf() instead... Or, asprintf(), if that's been around longer... Or, hell, you could always have just fprintf()'d to a temp file, checked the size, allocated a buffer, and read the file back in... Oh, wait, you said "sane"... ;-)

I just thought the same "Oh noes, truncation!!!" worries applied to snprintf(), as well... And, frankly, I haven't heard of that causing major security nightmares anywhere yet... Has it?

The ups and downs of strlcpy()

Posted Jul 19, 2012 23:11 UTC (Thu) by nix (subscriber, #2304) [Link]

I said 'sane' but I assumed 'portable': this stuff had to run on Solaris as well as Linux. Neither asprintf() nor open_memstream() are portable, alas.

The ups and downs of strlcpy()

Posted Jul 20, 2012 10:09 UTC (Fri) by RobSeace (subscriber, #4435) [Link]

Ah, I thought we were just talking about the rationale for getting accepted into glibc or not... Was it just that snprintf() was accepted by POSIX/ISO, so glibc was forced to accept it as a standard, while strl*() wasn't?

The ups and downs of strlcpy()

Posted Jul 20, 2012 12:44 UTC (Fri) by nix (subscriber, #2304) [Link]

Ah, right. From a *user's* perspective we cannot use open_memstream() et al because they are not portable. From a *library developer's* perspective we shouldn't introduce strlcpy() because it sucks and everyone should just use open_memstream(). :)

Obviously the only real solution is to write your own string abstraction using counted strings or whatever floats your boat...

The ups and downs of strlcpy()

Posted Jul 20, 2012 4:18 UTC (Fri) by cmccabe (guest, #60281) [Link]

Yeah, the debate over strlcpy doesn't make a whole lot of sense.

Programmers who want to check for truncation will find it easier to do with strlcpy. It requires fewer lines of code. That makes it easier to audit the code and find bugs. Programmers who don't want to check for truncation aren't going to do so anyway, no matter what API you add or don't add to the standard library.

C is a fundamentally different language than most of the modern languages out there. It's not managed. There will always be a way for the programmer to screw up. People seem to not grasp this concept. They think strlcpy should not be added, because somewhere-- maybe hiding under the couch-- is a perfect function which will magically make copying strings in C safe, like in the managed languages. There isn't.

The ups and downs of strlcpy()

Posted Jul 20, 2012 21:08 UTC (Fri) by smurf (subscriber, #17840) [Link]

Not to mention the fact that you don't need two passes through your string.

Look, we all know that there's no magic bullet in programming. Different tools do different parts of the job well, others … not so much.

Fortunately, there are two quite simple workarounds for not having strlcpy in libc:

* add -lbsd to your GCC command line.

* #define strlcpy(d,n,s) snprintf((d),(n),"%s",(s))

Which of these is more efficient is left as an exercise to the reader. :-P

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds