This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implement C11 annex K?


On Fri, 15 Aug 2014 19:43:35 -0300, Adhemerval Zanella <azanella@linux.vnet.ibm.com> wrote:
> Well, from last kernel developers iterations [1], I would say these functions 
> are also not well-liked in Linux...
> [1] https://plus.google.com/111049168280159033135/posts/1amLbuhWbh5


Well, let's take a look...

 
>David Herrmann originally shared:
>> A big thanks to BSD for introducing the safe strlcpy as replacement for strncpy. There's no unexpected behavior anymo-- wait, no.. oh god! strlcpy requires the source to be 0 terminated, even if its longer than the target size. Why? Of course, so the return-value can be the length of the string that was tried to be written, instead of the real written length.
> Not the first time I see kernel-patches replacing the good old:
> strncpy(kernel, from_user, len - 1) + kernel[len] = 0
> with:
> strlcpy(kernel, from_user, len)

The "recommended" approach using strncpy is absurd.  As Linus Torvalds quickly responds on Jul 28, 2014
> Well, to be fair, "strncpy()" sucks too. It does the insane "pad with zero" which is a performance disaster with any sanely sized buffers.

Good thing we have snprintf to the rescue!! Oh wait, that *also* reads from the source even if it's longer than the target size.

I actually think that David Herrmann has a good point.  However, the usually-recommended alternatives, strncpy and snprintf, have the same semantics. If strlcpy/strlcat are to be faulted for this, then strncpy and snprintf should be rejected for the same reasons.


Now, it *is* true that Linus Torvalds continues with:
>  And yeah, the strlcpy return value is broken by design.
> If you're actually copying from user space in the kernel, do
>   ret = strncpy_from_user(buf, userptr, len);
>   if (ret < 0) return ret;
>   if (ret == len) return -ETOOLONG;

There is no similar function in glibc to my knowledge.  (I think the return value should just be negative if the data reaches len, to simplify truncation handling and force a strlcpy-like guarantee that the dest is terminated if it has length.)  Would something like that be more acceptable, since that would overcome the objection above, and obviously the Linux kernel developers *do* use a special copying routine for copying up to a given length into fixed-size buffers?

--- David A. Wheeler


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]