Martijn van Duren <openbsd+t...@list.imperialat.at> wrote: > I think the others have given a decent explanation, but I would like to > elaborate a little furter.
I strongly agree with your points, but a few comments. > OK, so strscpy won't read any more data from src than count bytes, which > could save you from reading from the end of the world, where strlcpy > does assume that src is a NUL-terminated string. In C, a string is a NUL-terminated byte sequence. If it isn't NUL-terminated, then it isn't a string. The language feature "char []" does this, and the string-function subset of the language RELY upon this. strlcpy follows that same pattern. We don't need to say "C string", it is clear enough to say "string". > src is clearly not a C-string, since it's not NUL-terminated, but > there's no problem, since strscpy doesn't throw us over the edge of the > world. Right? Oh my god, strlen also fails. Because the object isn't a string. That much is clear. > The problem is that you don't know what comes after src. It could be > sensitive information that's now being made available to an attacker, it > could introduce byte-sequences that completely blow up your terminal. > You just can't tell for sure. With strlcpy chances are greater that you > hit a page that's not mapped readable and you generate a SEGFAULT. > Like Joel said in his talk, it's better to crash and fix the bug. Indeed. Most OpenBSD security changes have focused on converting subtle failure conditions into quick & hard failures, rather than allowing code to continue running after creating the first instance of damage. > Note that I'm not familiar enough with the kernel to make any statement > on whether on not things work identically there. Same thing in the kernel. An aggressive over-access is likely to run into an unmapped page of memory, and kaboom you crash, which is good because now you know of a bug you didn't know previously. (1) the bug is less easily be exploited by an attacker since the common case crashes instead of leaving a damage artifact in memory, and (2) you know before the attacker, and (3) it is a priority for repair. > If you want to be 100% secure you'd need to keep track of both the src > length (note that's the length of the string and not of the allocated > memory) and the destination buffer size and built a set of string > manipulation functions around that. But that would be a lot more tedious > to use and one could just as easily overlook to change the length > attribute upon change, which brings you back to square one. The strlcpy paper described this as a design decision. Easy for people to incorporate the overflow-protection. Overflow-detection and handling is another problem. strlcpy also makes this easy, but a glance at our whole source tree demonstrates how un-urgent the extended software development community takes that problem, meaning we seldom receive diffs to add checks. As to strlcpy walking the whole string and determining the required length, that's the same behaviour as snprintf. So strlcpy is mergely copying the interface of an existing function in the standard. The enemy of the good is the perfect, and that enemy foams at the mouth about imperfection and then turns around and doesn't fix any software. > I'm not certain what the author tries to say with "the implementation > is robust to the string changing out from underneath it", so I won't > comment on that part. It must be grabbing the big string lock.