[PATCH v7] Implement strlcpy, strlcat [BZ #178]

Alexander Cherepanov ch3root@openwall.com
Sun Jan 10 23:29:00 GMT 2016


On 2016-01-09 01:31, Paul Eggert wrote:
> Alexander Cherepanov wrote:
>
>> it's handy
>
> No, because even if that example's silent-truncation bug were fixed
> (which is yet another bit of evidence against strlcpy!),

Hm, strlcpy doesn't really differ from an ordinary strlen in this 
regard, so I'm not sure to which degree this is evidence against strlcpy 
and to which -- against C strings. Perhaps the problem is that all 
official examples of strlcpy are of the form "len = strlcpy(...); if 
(len >= size) ..." (that is, no "+ 1" here) while for strlen it's quite 
common to write "strlen(...) + 1" (that is, adding one right away).

OTOH such a bug with strlen will lead to buffer overflow instead of 
truncation. Not really better:-)

> its use case is
> already well-addressed by the standard API, and portable programs can
> (and already do) use something like the following instead.

This could be an argument against addition of strlcpy in general but 
specifically for size=0 it seems to confirm importance of the case:-)

>> you can catch size=0 with strlcat even if strlcpy accepts size=0
>> without triggering any protections.
>
> No, because often only strlcpy is executed, with strlcat used only in
> relatively unusual circumstances.

Ok, I misunderstood you.

> There are sound software-engineering
> reasons for insisting that strlcpy be no less reliable and strict than
> strlcat,

Given that strlcat 'dest' argument is often prepared by strlcpy I can 
see why strlcpy should be not less reliable than strlcat -- there is 
just no reason for strlcat to be more robust than strclpy. But why 
strlcpy should be no less strict than strlcat?

> and for the two functions to follow the same rules.

The functions are different and it's not entirely clear what you mean 
exactly.

One possible guiding principle: strlcat should be able to accept 
anything after strlcpy. This would mean that it should accept size=0 if 
strlcpy does it but not other non-null-terminated dest arrays.

But taken in isolation strlcat for non-null-terminated dest arrays 
(including the case of size=0) is somewhat different from strlcpy for 
size=0: the result of strlcpy with size=0 is the amount of memory you 
have to allocate for a successful retry, the result of strlcat with a 
non-null-terminated dest array is mostly useless because the length of 
dest is still unknown.

OTOH strlcat is sometimes used after snprintf (~40 cases in OpenBSD 
sources). Does it mean that strlcat should be as reliable and strict as 
snprintf?

>> be conservative in what you document, be liberal in what you implement.
>
> Yes, that's a goal of my most recently-proposed documentation. Again, I
> don't think we should add strlcpy+strlcat to glibc; but if we do add
> them, we should document them conservatively.

I guess this implies that it should be documented in the sources which 
guarantees the implementation provides in addition to those in the 
user-facing manual so that it's not broken later by someone looking only 
at the manual.

-- 
Alexander Cherepanov



More information about the Libc-alpha mailing list