Message ID | 56326B79.8070804@redhat.com |
---|---|
State | New |
Headers | show |
I support the addition of this API as sufficiently widely used in practice, but have not reviewed the substance of the patch. > diff --git a/debug/strlcpy_chk.c b/debug/strlcpy_chk.c > new file mode 100644 > index 0000000..038d8f9 > --- /dev/null > +++ b/debug/strlcpy_chk.c > @@ -0,0 +1,29 @@ > +/* Copyright (C) 2015 Free Software Foundation, Inc. The first line of any new file should be a descriptive comment, before the copyright notice. > diff --git a/string/strlcpy.c b/string/strlcpy.c > new file mode 100644 > index 0000000..9b39d86 > --- /dev/null > +++ b/string/strlcpy.c > @@ -0,0 +1,46 @@ > +/* Copyright (C) 2015 Free Software Foundation, Inc. Likewise. > +size_t > +strlcpy(char *__restrict dest, const char *__restrict src, size_t size) Missing space before '('. > diff --git a/string/tst-strlcpy.c b/string/tst-strlcpy.c > new file mode 100644 > index 0000000..016411b > --- /dev/null > +++ b/string/tst-strlcpy.c Missing descriptive comment.
I'd rather we didn't add strlcpy to glibc, for reasons already discussed. If consensus goes against me, the patch still needs some work. I don't recall the details of our previous discussion; at the risk of reraising old issues here are some comments: * If strlen(SRC) < DESTLEN, the documentation should clearly state that the contents of the bytes DEST[strlen(SRC) + 1] through DEST[DESTLEN - 1] are preserved. The current documentation can be plausibly read that way, but it's not explicit. * The proposed documentation can easily be misread as implying that strlcpy (DEST, SRC, DESTLEN) does O(DESTLEN) work, which is incorrect: strlcpy always does O(strlen(SRC)) work. This point should be made clearly. This is not merely a performance issue: it should be made crystal-clear that SRC must be null-terminated even if the source's trailing null byte is way after the bytes that strlcpy copies to DEST. * strlcpy's name should be prefixed by '__' by default. The names strlcpy and strlcpy_chk are both in the implementation namespace, and it's odd to have one without leading underscores and the other with them. I suggest a more cautious approach, in which both names are prefixed with '__' and unprefixed strlcpy is provided to the user only when GNU or BSD extensions are requested via _GNU_SOURCE etc. This is less likely to break existing applications. It's true that POSIX and the C standard allow glibc to add str* names of all sorts, but it doesn't hurt to be realistic here about the user code that's undoubtedly out there. * strlcpy's implementation should use memmove instead of memcpy. The main motivations for strlcpy are safety and consistency and avoiding errors. memmove obviously supports these goals better than memcpy does. Efficiency is not a major concern with strlcpy (if it were, strlcpy wouldn't be O(strlen(SRC))). > +Not guaranteeing null termination and always overwriting the entire > +destination buffer makes @code{strncpy} rarely useful, but this behavior > +is specified by the @w{ISO C} standard. See @code{strlcpy} below for an > +alternative. This quote is confusing, as it imples that strlcpy guarantees null termination, which strlcpy does not. I suggest rewording it to something like the following: "Often @code{strncpy} is not what you want, because it does not null-terminate the destination if the destination is smaller than the source, it always overwrites the entire destination buffer, it may truncate the destination, and it has undefined behavior if the source and destination overlap. For alternatives, see the documentation below for @code{strlcpy}." We can pair this with similar phrasing under strlcpy -- something like the following perhaps (this wording assumes strlcpy is changed to use memmove):"Often @code{strlcpy} is not what you want, because it does not null-terminate the destination if the destination's size is zero,it can leave junk data behind in the destination, it can do useless work when the source is long and the destination short, and it may truncate the destination. Although one alternative is @code{strncpy}, it is usually better to use dynamic memory allocation and functions such as @code{strdup} or @code{asprintf} to construct strings."
On 10/29/2015 02:50 PM, Paul Eggert wrote: > We can pair this with similar phrasing under strlcpy -- something like > the following perhaps (this wording assumes strlcpy is changed to use > memmove):"Often @code{strlcpy} is not what you want, because it does > not null-terminate the destination if the destination's size is > zero,it can leave junk data behind in the destination, it can do > useless work when the source is long and the destination short, and it > may truncate the destination. Although one alternative is > @code{strncpy}, it is usually better to use dynamic memory allocation > and functions such as @code{strdup} or @code{asprintf} to construct > strings." One more thing: we should add "it requires the source to be null-terminated even when it is longer than the destination".
On Thu, Oct 29, 2015 at 02:50:54PM -0700, Paul Eggert wrote: > I'd rather we didn't add strlcpy to glibc, for reasons already > discussed. If consensus goes against me, the patch still needs some > work. I don't recall the details of our previous discussion; at the > risk of reraising old issues here are some comments: > > * If strlen(SRC) < DESTLEN, the documentation should clearly state > that the contents of the bytes DEST[strlen(SRC) + 1] through > DEST[DESTLEN - 1] are preserved. The current documentation can be > plausibly read that way, but it's not explicit. I don't think this needs to be explicit. There is a general principle, which needs to be promoted rather than undermined, that a function cannot have side effects/alter the value of objects outside of its documented behavior. > * The proposed documentation can easily be misread as implying that > strlcpy (DEST, SRC, DESTLEN) does O(DESTLEN) work, which is > incorrect: strlcpy always does O(strlen(SRC)) work. This point > should be made clearly. This is not merely a performance issue: it > should be made crystal-clear that SRC must be null-terminated even > if the source's trailing null byte is way after the bytes that > strlcpy copies to DEST. I'm not opposed to making a more visible warning, but the documentation of the return value should make it clear. Requiring the argument to point to "a string" also expresses the null termination requirement. This is the same language used in the C standard for string functions. > * strlcpy's name should be prefixed by '__' by default. The names > strlcpy and strlcpy_chk are both in the implementation namespace, > and it's odd to have one without leading underscores and the other > with them. I suggest a more cautious approach, in which both names > are prefixed with '__' and unprefixed strlcpy is provided to the > user only when GNU or BSD extensions are requested via _GNU_SOURCE > etc. This is less likely to break existing applications. It's true > that POSIX and the C standard allow glibc to add str* names of all > sorts, but it doesn't hurt to be realistic here about the user code > that's undoubtedly out there. The function should only be exposed at all when extensions are exposed (_DEFAULT_SOURCE/_ALL_SOURCE) but __-prefixed functions should never be a public API intended for applications to use. Also exposing the function with a name different from widespread usage would not help application portability. > * strlcpy's implementation should use memmove instead of memcpy. The > main motivations for strlcpy are safety and consistency and avoiding > errors. memmove obviously supports these goals better than memcpy > does. Efficiency is not a major concern with strlcpy (if it were, > strlcpy wouldn't be O(strlen(SRC))). No, the fortify version should just abort when this contract is broken. Invalid usage contrary to documentation should not be silently supported. This encourages non-portable programs which would break on other strl* implementations. Rich
Rich Felker wrote: > There is a general principle, > which needs to be promoted rather than undermined, that a function > cannot have side effects/alter the value of objects outside of its > documented behavior. Regardless of whether that is an (undocumented?) general principle, this is a user manual not a formal standard. In this particular context it's helpful to describe strlcpy's behavior carefully, since it's explained right after strncpy's and the reader might otherwise easily get confused into the misimpression that strlcpy behaves like strncpy except for guaranteeing null-termination when DESTLEN is nonzero. > Requiring the > argument to point to "a string" also expresses the null termination > requirement. This is the same language used in the C standard for > string functions. Again, the point of the documentation is to be clear and useful, and it's helpful to spell things out given the strncpy context. (Besides, this is a manual that contains phrases like "it is more efficient and works even if the string @var{s} is not null-terminated", so it's a bit much to expect the reader to know that "string" always means "null-terminated". :-) > __-prefixed functions should never > be a public API intended for applications to use. Yes, that's fine. My point was about the non-'__'-prefixed name, where it appears we agree. > No, the fortify version should just abort when this contract is > broken. The idea was that this contract should be memmove-based, not memcpy-based, which means the fortify version would not abort if the arguments overlap. Still, I see your point: if we wanted move semantics, we'd have called the function 'strlmove' or something like that. So I withdraw the suggestion to change the contract, and instead suggest that we add overlapping strings to our list of when not to use strlcpy, e.g,: Often @code{strlcpy} is not what you want, because it does not null-terminate the destination if the destination's size is zero, it can leave junk data behind in the destination, it can do useless work when the source is long and the destination short, it requires the source to be null-terminated even when it is longer than the destination, it can crash if the source and destination overlap, and it may truncate the destination. Although one alternative is @code{strncpy}, it is usually better to use dynamic memory allocation and functions such as @code{strdup} or @code{asprintf} to construct strings. All in all, I'd still rather not add this poorly-designed API to the library.
On Sat, Oct 31, 2015 at 03:37:10AM -0700, Paul Eggert wrote: > Rich Felker wrote: > > >There is a general principle, > >which needs to be promoted rather than undermined, that a function > >cannot have side effects/alter the value of objects outside of its > >documented behavior. > > Regardless of whether that is an (undocumented?) general principle, > this is a user manual not a formal standard. In this particular > context it's helpful to describe strlcpy's behavior carefully, since > it's explained right after strncpy's and the reader might otherwise > easily get confused into the misimpression that strlcpy behaves like > strncpy except for guaranteeing null-termination when DESTLEN is > nonzero. OK, I can agree with this. > >Requiring the > >argument to point to "a string" also expresses the null termination > >requirement. This is the same language used in the C standard for > >string functions. > > Again, the point of the documentation is to be clear and useful, and > it's helpful to spell things out given the strncpy context. > (Besides, this is a manual that contains phrases like "it is more > efficient and works even if the string @var{s} is not > null-terminated", so it's a bit much to expect the reader to know > that "string" always means "null-terminated". :-) Likewise ok. > >__-prefixed functions should never > >be a public API intended for applications to use. > > Yes, that's fine. My point was about the non-'__'-prefixed name, > where it appears we agree. > > >No, the fortify version should just abort when this contract is > >broken. > > The idea was that this contract should be memmove-based, not glibc's role here is not to design the contract but to implement the existing contract precisely. This is because the whole goal of providing these functions in glibc is to reduce subtle errors from people reimplementing fallbacks in slightly-incompatible ways, not to design a new API that we want to recommend people use. > All in all, I'd still rather not add this poorly-designed API to the library. Noted. Rich
I still concur with Paul that we should not have this API in libc.
On Thu, Nov 05, 2015 at 01:11:04PM -0800, Roland McGrath wrote:
> I still concur with Paul that we should not have this API in libc.
I think we're in agreement that it's not a "good API", but nonetheless
I see strong reasons for including them and no non-ideological reasons
not to. These have been covered in detail before so I won't repeat
them again unless you really want me to. Do you disagree with my
reasoning here?
Rich
On 06-11-2015 02:01, Rich Felker wrote: > On Thu, Nov 05, 2015 at 01:11:04PM -0800, Roland McGrath wrote: >> I still concur with Paul that we should not have this API in libc. > > I think we're in agreement that it's not a "good API", but nonetheless > I see strong reasons for including them and no non-ideological reasons > not to. These have been covered in detail before so I won't repeat > them again unless you really want me to. Do you disagree with my > reasoning here? > > Rich > Roland, I tend to agree with Paul also, but nonetheless any reasoning against this API is not refraining developers to continue reimplement and use this set of functions.
On 11/06/2015 01:09 PM, Adhemerval Zanella wrote: > > > On 06-11-2015 02:01, Rich Felker wrote: >> On Thu, Nov 05, 2015 at 01:11:04PM -0800, Roland McGrath wrote: >>> I still concur with Paul that we should not have this API in libc. >> >> I think we're in agreement that it's not a "good API", but nonetheless >> I see strong reasons for including them and no non-ideological reasons >> not to. These have been covered in detail before so I won't repeat >> them again unless you really want me to. Do you disagree with my >> reasoning here? >> >> Rich >> > > Roland, I tend to agree with Paul also, but nonetheless any reasoning > against this API is not refraining developers to continue reimplement > and use this set of functions. My understanding is that there are several arguments for adding this API (e.g., widely used in existing open source projects, performance, specific existing use cases, portability) and against (e.g., encourages possible security issues, additional maintenance, similar-to-existing-API-but-yet-different-approach). As a mere user, I have never needed strlcpy myself. Given that this function is quite easy to realize, I see no reason to include such a function in glibc. Also, I see only little value in improving the portability with BSDs beyond POSIX, really. Thus, the real value of adding this function appears to be convenience reasons. Anyway, this is my personal view. As Rich stated, the arguments have been on the table several times and it is not my intent to restart the discussion. Instead, my proposal is to add this function to glibc, but in a separate library. Also, I would like to see a comment like "Do not use this function unless you really know what you do. Consider strncpy instead." in the documentation (and man pages, eventually). Thoughts?
On Sun, Nov 08, 2015 at 01:48:38AM +0100, Tolga Dalman wrote: > As a mere user, I have never needed strlcpy myself. Given that this > function is quite easy to realize, I see no reason to include such > a function in glibc. Unfortunately that's NOT a given. Most reimplementations from scratch have at least one serious corner-case bug. And if you have more than one in the same program (e.g. multiple shared libraries that each implement their own) they all end up using the copy from whichever library was linked first, which might have a corner-case bug that affects the other users. This is the main compelling security reason for having the functions in libc: to get programs/libraries to stop providing their own likely-buggy versions. > Also, I see only little value in improving the > portability with BSDs beyond POSIX, really. Thus, the real value of > adding this function appears to be convenience reasons. Anyway, this > is my personal view. As Rich stated, the arguments have been on the > table several times and it is not my intent to restart the discussion. > > Instead, my proposal is to add this function to glibc, but in a separate library. That is utterly useless and much more costly. Each additional library linked adds at least 4k of (non-shareable) memory usage to a process and increases the start time by tens or hundreds of microseconds. But most importantlu, if they're not available in the default link, configure scripts will never find/use them, and they'll just end up enabling their own replacements. Anyway, in general, if adding a function to glibc is a bad idea, adding it in its own separate .so file shipped with glibc is an even worse idea. There are no advantages and lots of disadvantages. Rich
On 11/08/2015 02:07 AM, Rich Felker wrote: > On Sun, Nov 08, 2015 at 01:48:38AM +0100, Tolga Dalman wrote: >> As a mere user, I have never needed strlcpy myself. Given that this >> function is quite easy to realize, I see no reason to include such >> a function in glibc. > > Unfortunately that's NOT a given. Most reimplementations from scratch > have at least one serious corner-case bug. And if you have more than > one in the same program (e.g. multiple shared libraries that each > implement their own) they all end up using the copy from whichever > library was linked first, which might have a corner-case bug that > affects the other users. This is the main compelling security reason > for having the functions in libc: to get programs/libraries to stop > providing their own likely-buggy versions. It is difficult to discuss about this topic in an abstract manner. I believe that most uses of strlcpy and strlcat are really unjustified as they could be easily replaced by strncat/strcpy. As I wrote above, this is just my personal (perhaps naïve) view. Can you send me a list of concrete examples where the specific features of these functions are necessary (e.g., the memory beyond \0 must not be written)? If performance is really the reason, I would like to review some benchmarks before continuing the discussion at that point. >> Also, I see only little value in improving the >> portability with BSDs beyond POSIX, really. Thus, the real value of >> adding this function appears to be convenience reasons. Anyway, this >> is my personal view. As Rich stated, the arguments have been on the >> table several times and it is not my intent to restart the discussion. >> >> Instead, my proposal is to add this function to glibc, but in a separate library. > > That is utterly useless and much more costly. Each additional library > linked adds at least 4k of (non-shareable) memory usage to a process > and increases the start time by tens or hundreds of microseconds. But > most importantlu, if they're not available in the default link, > configure scripts will never find/use them, and they'll just end up > enabling their own replacements. > > Anyway, in general, if adding a function to glibc is a bad idea, > adding it in its own separate .so file shipped with glibc is an even > worse idea. There are no advantages and lots of disadvantages. I am not talking about a libstrlcpy but instead something like libbsd_ext. Again, we are talking quite abstractly about applications. Do you have a list of open source applications that use strlcpy or strlcat? Anyway, I note that you are quick to argue against my idea. What is your proposal to resolve the issue in glibc?
On Sun, Nov 08, 2015 at 02:41:27AM +0100, Tolga Dalman wrote: > On 11/08/2015 02:07 AM, Rich Felker wrote: > > On Sun, Nov 08, 2015 at 01:48:38AM +0100, Tolga Dalman wrote: > >> As a mere user, I have never needed strlcpy myself. Given that this > >> function is quite easy to realize, I see no reason to include such > >> a function in glibc. > > > > Unfortunately that's NOT a given. Most reimplementations from scratch > > have at least one serious corner-case bug. And if you have more than > > one in the same program (e.g. multiple shared libraries that each > > implement their own) they all end up using the copy from whichever > > library was linked first, which might have a corner-case bug that > > affects the other users. This is the main compelling security reason > > for having the functions in libc: to get programs/libraries to stop > > providing their own likely-buggy versions. > > It is difficult to discuss about this topic in an abstract manner. > I believe that most uses of strlcpy and strlcat are really unjustified > as they could be easily replaced by strncat/strcpy. As I wrote above, This is blatently wrong. strncpy is never a suitable repacement for strlcpy. Its usage case is completely different: fixed-field-width, non-null-terminated strings. These are largely obsolete (mainly used in legacy on-disk data), and so is strncpy. > this is just my personal (perhaps naïve) view. > Can you send me a list of concrete examples where the specific features > of these functions are necessary (e.g., the memory beyond \0 must not > be written)? That's not the main problem. Lack of null termination is a much bigger problem. The biggest problem is that nobody understands it or knows how to use it safely. > If performance is really the reason, I would like to review some > benchmarks before continuing the discussion at that point. There were historically a number of programs which had really bad performance because they were misusing strncpy for this purpose, with very large buffers. I recall participating in the bug tracker tickets for them, but I don't have links handy now. This was probably more than a decade ago; people have mostly stopped the practice. > >> Also, I see only little value in improving the > >> portability with BSDs beyond POSIX, really. Thus, the real value of > >> adding this function appears to be convenience reasons. Anyway, this > >> is my personal view. As Rich stated, the arguments have been on the > >> table several times and it is not my intent to restart the discussion. > >> > >> Instead, my proposal is to add this function to glibc, but in a separate library. > > > > That is utterly useless and much more costly. Each additional library > > linked adds at least 4k of (non-shareable) memory usage to a process > > and increases the start time by tens or hundreds of microseconds. But > > most importantlu, if they're not available in the default link, > > configure scripts will never find/use them, and they'll just end up > > enabling their own replacements. > > > > Anyway, in general, if adding a function to glibc is a bad idea, > > adding it in its own separate .so file shipped with glibc is an even > > worse idea. There are no advantages and lots of disadvantages. > > I am not talking about a libstrlcpy but instead something like libbsd_ext. > Again, we are talking quite abstractly about applications. Do you have > a list of open source applications that use strlcpy or strlcat? Someone came up with one the last time this was discussed, I think. You can search the libc-alpha archives. > Anyway, I note that you are quick to argue against my idea. What is your > proposal to resolve the issue in glibc? My proposal has always been to implement it in glibc with the correct semantics matching the original BSD function in all corner cases, document it well, and note that it's not recommended but without throwing too much ideology/propaganda into that note. Rich
On Sat, 7 Nov 2015, Rich Felker wrote: > Anyway, in general, if adding a function to glibc is a bad idea, > adding it in its own separate .so file shipped with glibc is an even > worse idea. There are no advantages and lots of disadvantages. While it's trivially true that "adding a function to glibc is a bad idea" means it's bad to add it to any library in glibc, existing or new, there may well be cases where the conclusion is "it's a good idea to add this function to glibc, but in a new library (which might be might not be linked in automatically via AS_NEEDED in a .so linker script)". Cf. libmvec or the libinux-syscalls.so.1 discussion. It's just that I don't see strlcpy, strlcat or explicit_bzero as such cases - I see them as cases that belong in libc.
On Mon, Nov 09, 2015 at 12:59:25PM +0000, Joseph Myers wrote: > On Sat, 7 Nov 2015, Rich Felker wrote: > > > Anyway, in general, if adding a function to glibc is a bad idea, > > adding it in its own separate .so file shipped with glibc is an even > > worse idea. There are no advantages and lots of disadvantages. > > While it's trivially true that "adding a function to glibc is a bad idea" > means it's bad to add it to any library in glibc, existing or new, there > may well be cases where the conclusion is "it's a good idea to add this > function to glibc, but in a new library (which might be might not be > linked in automatically via AS_NEEDED in a .so linker script)". Cf. > libmvec or the libinux-syscalls.so.1 discussion. It's just that I don't > see strlcpy, strlcat or explicit_bzero as such cases - I see them as cases > that belong in libc. Could you elaborate on when/how there would ever be a technical (not ideologically-motivated) reason to add additional .so's as part of glibc? I see all the ones we have (esp. libpthread and librt) as historical mistakes that have been a perpetual source of problems (like programs sticking with the deprecated gettimeofday instead of clock_gettime because the latter needed -lrt, and broken weak symbol hacks for pthreads like gcc pr57740, pr60662, or libxml2 pr704904) that we should aim to eliminate, not duplicate. Rich
On Mon, 9 Nov 2015, Rich Felker wrote: > Could you elaborate on when/how there would ever be a technical (not > ideologically-motivated) reason to add additional .so's as part of Are you saying libinux-syscalls.so.1 is ideologically motivated? libmvec is separate to allow for the possibility of using vector instructions that are only supported by binutils versions more recent than we wish to require as the minimum for a given architecture (this is a generic reason that could apply to multiple architectures) - the ABI provided by a library mustn't depend on the build tool version, but its presence or absence may. (This reasoning does *not* work for powerpc float128 functions - quite clearly TS 18661-3 functions belong in libc/libm rather than another library, since many would be aliases of existing functions, so float128 functions can only be added to glibc for an architecture when there's consensus on a suitable minimum GCC version for building libc for that architecture.) If libdfp were merged into glibc we'd need to consider carefully whether separate libraries or libc + libm were the way to go. Cf. <https://gcc.gnu.org/ml/gcc-patches/2008-08/msg00870.html> regarding DFP support in libgcc being static-only to avoid making libgcc_s 8 times bigger for rarely used functionality (also raising concerns there about number of runtime relocations and size of writable segment, though without answers there).
On 11/09/2015 07:59 AM, Joseph Myers wrote: > On Sat, 7 Nov 2015, Rich Felker wrote: > >> Anyway, in general, if adding a function to glibc is a bad idea, >> adding it in its own separate .so file shipped with glibc is an even >> worse idea. There are no advantages and lots of disadvantages. > > While it's trivially true that "adding a function to glibc is a bad idea" > means it's bad to add it to any library in glibc, existing or new, there > may well be cases where the conclusion is "it's a good idea to add this > function to glibc, but in a new library (which might be might not be > linked in automatically via AS_NEEDED in a .so linker script)". Cf. > libmvec or the libinux-syscalls.so.1 discussion. It's just that I don't > see strlcpy, strlcat or explicit_bzero as such cases - I see them as cases > that belong in libc. I agree. Cheers, Carlos.
On Mon, Nov 09, 2015 at 06:31:32PM +0000, Joseph Myers wrote: > On Mon, 9 Nov 2015, Rich Felker wrote: > > > Could you elaborate on when/how there would ever be a technical (not > > ideologically-motivated) reason to add additional .so's as part of > > Are you saying libinux-syscalls.so.1 is ideologically motivated? Yes, so far all of the arguments I've seen for it have been that somebody does not want them in libc.so because they're not the "GNU API". I haven't seen any technical problem that's solved by putting them in a separate .so, but of course there are technical problems created (more memory usage and startup time, etc.). > libmvec is separate to allow for the possibility of using vector > instructions that are only supported by binutils versions more recent than > we wish to require as the minimum for a given architecture (this is a > generic reason that could apply to multiple architectures) - the ABI > provided by a library mustn't depend on the build tool version, but its > presence or absence may. This seems like a legitimate technical concern, but I don't think it's the right solution. Instructions that aren't supported by the minimum binutils version probably need to be represented with .byte or similar until the version requirement is increased. IMO it's the whole combined API/ABI of all the glibc libs, not just individual libs, that should be independent of the tools used to build. Rich
I don't have an opinion on strlcpy itself, but I've been following this discussion and I think the best compromise I've heard is found in these two statements: On 11/07/2015 04:48 PM, Tolga Dalman wrote: > Also, I would like to see a comment like "Do not use this function unless > you really know what you do. Consider strncpy instead." in the documentation > (and man pages, eventually). On 11/07/2015 05:51 PM, Rich Felker wrote: > My proposal has always been to implement it in glibc with the correct > semantics matching the original BSD function in all corner cases, > document it well, and note that it's not recommended but without > throwing too much ideology/propaganda into that note. As a glibc user, I take the manual at its word. If it says to avoid use of a function (and there are quite a few it says that about*), I will. Rather than inclusion in glibc and subsequent blacklisting via the manual though, I don't see any harm in providing documentation to the effect of, "These are the appropriate use cases for this function; otherwise it should be avoided." I appreciate that some people want to provide what they feel is a safer implementation of an error-prone routine. Despite a pathological urge to always reinvent the wheel, that is exactly one of the things I rely on the providers of my C library (you all) to do. Rical * Some examples: https://www.gnu.org/software/libc/manual/html_node/Charset-Function-Overview.html#Charset-Function-Overview https://www.gnu.org/software/libc/manual/html_node/Basic-Signal-Handling.html#Basic-Signal-Handling https://www.gnu.org/software/libc/manual/html_node/Formatted-Output-Functions.html#Formatted-Output-Functions
On 11/09/2015 01:16 PM, Rich Felker wrote: > On Mon, Nov 09, 2015 at 12:59:25PM +0000, Joseph Myers wrote: >> On Sat, 7 Nov 2015, Rich Felker wrote: >> >>> Anyway, in general, if adding a function to glibc is a bad idea, >>> adding it in its own separate .so file shipped with glibc is an even >>> worse idea. There are no advantages and lots of disadvantages. >> >> While it's trivially true that "adding a function to glibc is a bad idea" >> means it's bad to add it to any library in glibc, existing or new, there >> may well be cases where the conclusion is "it's a good idea to add this >> function to glibc, but in a new library (which might be might not be >> linked in automatically via AS_NEEDED in a .so linker script)". Cf. >> libmvec or the libinux-syscalls.so.1 discussion. It's just that I don't >> see strlcpy, strlcat or explicit_bzero as such cases - I see them as cases >> that belong in libc. > > Could you elaborate on when/how there would ever be a technical (not > ideologically-motivated) reason to add additional .so's as part of > glibc? I see all the ones we have (esp. libpthread and librt) as > historical mistakes that have been a perpetual source of problems > (like programs sticking with the deprecated gettimeofday instead of > clock_gettime because the latter needed -lrt, and broken weak symbol > hacks for pthreads like gcc pr57740, pr60662, or libxml2 pr704904) > that we should aim to eliminate, not duplicate. FWIW, I tend to agree with this. zw
2015-10-29 Florian Weimer <fweimer@redhat.com> [BZ #178] * string/Makefile (routines): Add strlcpy. (tests): Add tst-strlcpy. * string/Versions (2.21): Export strlcpy. * string/strlcpy.c: New file. * string/tst-strlcpy.c: Likewise. * include/string.h (strlcpy): Declare as hidden. * manual/string.texi (Copying and Concatenation): Document strlcpy. Update strncpy documentation. * debug/Makefile (routines): Add strlcpy_chk. * debug/Versions (2.21): Export __strlcpy_chk. * debug/tst-chk1.c (doit): Test strlcpy. * debug/strlcpy_chk.c: New file. * sysdeps/*/libc.abilist: Add strlcpy, __strlcpy_chk. diff --git a/NEWS b/NEWS index 0831d35..af7e375 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,7 @@ Version 2.23 * The following bugs are resolved with this release: - 887, 2542, 2543, 2558, 2898, 4404, 6803, 10432, 14341, 14912, 15367, + 178, 887, 2542, 2543, 2558, 2898, 4404, 6803, 10432, 14341, 14912, 15367, 15384, 15470, 15491, 15786, 15918, 16068, 16141, 16296, 16347, 16399, 16415, 16422, 16517, 16519, 16520, 16521, 16620, 16734, 16973, 16985, 17118, 17243, 17244, 17250, 17404, 17441, 17787, 17886, 17887, 17905, @@ -23,6 +23,8 @@ Version 2.23 19074, 19076, 19077, 19078, 19079, 19085, 19086, 19088, 19094, 19095, 19124, 19125, 19129, 19134, 19137, 19156, 19174, 19181. +* The GNU C Library now includes an implementation of strlcpy. + * A defect in the malloc implementation, present since glibc 2.15 (2012) or glibc 2.10 via --enable-experimental-malloc (2009), could result in the unnecessary serialization of memory allocation requests across threads. diff --git a/debug/Makefile b/debug/Makefile index a383417..f6cebab 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -30,6 +30,7 @@ headers := execinfo.h routines = backtrace backtracesyms backtracesymsfd noophooks \ memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \ strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \ + strlcpy_chk \ sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \ printf_chk fprintf_chk vprintf_chk vfprintf_chk \ gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \ diff --git a/debug/Versions b/debug/Versions index 0482c85..60a7aed 100644 --- a/debug/Versions +++ b/debug/Versions @@ -55,6 +55,9 @@ libc { GLIBC_2.16 { __poll_chk; __ppoll_chk; } + GLIBC_2.23 { + __strlcpy_chk; + } GLIBC_PRIVATE { __fortify_fail; } diff --git a/debug/strlcpy_chk.c b/debug/strlcpy_chk.c new file mode 100644 index 0000000..038d8f9 --- /dev/null +++ b/debug/strlcpy_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <memcopy.h> + +size_t +__strlcpy_chk (char *__restrict s1, const char *__restrict s2, + size_t n, size_t s1len) +{ + if (__glibc_unlikely (s1len < n)) + __chk_fail (); + + return strlcpy (s1, s2, n); +} diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c index bded583..0805a85 100644 --- a/debug/tst-chk1.c +++ b/debug/tst-chk1.c @@ -415,6 +415,10 @@ do_test (void) strncpy (a.buf1 + (O + 6), "X", l0 + 4); CHK_FAIL_END + CHK_FAIL_START + strlcpy (buf, "", sizeof (buf) + 1); + CHK_FAIL_END + # if !defined __cplusplus || defined __va_arg_pack CHK_FAIL_START sprintf (a.buf1 + (O + 7), "%d", num1); diff --git a/include/string.h b/include/string.h index a684fd9..82413af 100644 --- a/include/string.h +++ b/include/string.h @@ -73,6 +73,7 @@ extern __typeof (strncasecmp_l) __strncasecmp_l; libc_hidden_proto (__mempcpy) libc_hidden_proto (__stpcpy) libc_hidden_proto (__stpncpy) +libc_hidden_proto (strlcpy) libc_hidden_proto (__rawmemchr) libc_hidden_proto (__strcasecmp) libc_hidden_proto (__strcasecmp_l) diff --git a/manual/string.texi b/manual/string.texi index 5f8a17e..cc44201 100644 --- a/manual/string.texi +++ b/manual/string.texi @@ -576,17 +576,49 @@ there is no null terminator written into @var{to}. If the length of @var{from} is less than @var{size}, then @code{strncpy} copies all of @var{from}, followed by enough null characters to add up -to @var{size} characters in all. This behavior is rarely useful, but it -is specified by the @w{ISO C} standard. +to @var{size} characters in all. The behavior of @code{strncpy} is undefined if the strings overlap. -Using @code{strncpy} as opposed to @code{strcpy} is a way to avoid bugs +Not guaranteeing null termination and always overwriting the entire +destination buffer makes @code{strncpy} rarely useful, but this behavior +is specified by the @w{ISO C} standard. See @code{strlcpy} below for an +alternative. +@end deftypefun + +@comment string.h +@comment BSD +@deftypefun size_t strlcpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size}) +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +This function is similar to @code{strcpy}, but copies at most @var{size} +characters into @var{to}, including the terminating null character. + +If the length of @var{from} is equal to or more than @var{size}, then +@code{strlcpy} copies just the first @samp{@var{size} - 1} characters. +As a special case, if @var{size} is zero, no bytes are written to +@var{to}. + +If the length of @var{from} is less than @var{size}, then @code{strlcpy} +copies all of @var{from}, followed by a single null character. + +The return value @var{result} of @code{strlcpy} is the length of the +string @var{from}. This means that @samp{@var{result} >= @var{size}} is +true whenever truncation occurs. + +The behavior of @code{strlcpy} is undefined if the strings overlap or if +the source or destination are null pointers. + +Using @code{strlcpy} as opposed to @code{strcpy} is a way to avoid bugs relating to writing past the end of the allocated space for @var{to}. -However, it can also make your program much slower in one common case: -copying a string which is probably small into a potentially large buffer. -In this case, @var{size} may be large, and when it is, @code{strncpy} will -waste a considerable amount of time copying null characters. +Unlike @code{strncpy}, @code{strlcpy} ensures that the destination +string is always null-terminated (unless the buffer size is zero), and +it does not fill the remaining part of the buffer with null characters. + +@strong{Note:} GNU programs should not use statically sized buffers for +storing strings. @xref{Semantics, , Writing Robust Programs, standards, +The GNU Coding Standards}. Instead of using @code{strlcpy}, it is +usually better to use dynamic memory allocation and functions such as +@code{strdup} or @code{asprintf} to construct strings. @end deftypefun @comment wchar.h diff --git a/string/Makefile b/string/Makefile index ebe9354..0d1fb52 100644 --- a/string/Makefile +++ b/string/Makefile @@ -41,7 +41,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \ addsep replace) \ envz basename \ strcoll_l strxfrm_l string-inlines memrchr \ - xpg-strerror strerror_l + xpg-strerror strerror_l strlcpy strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ @@ -54,7 +54,7 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \ tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \ bug-strtok1 $(addprefix test-,$(strop-tests)) \ bug-envz1 tst-strxfrm2 tst-endian tst-svc2 \ - tst-strtok_r bug-strcoll2 + tst-strtok_r bug-strcoll2 tst-strlcpy xtests = tst-strcoll-overflow diff --git a/string/Versions b/string/Versions index 59bf35a..bd00ca1 100644 --- a/string/Versions +++ b/string/Versions @@ -80,4 +80,7 @@ libc { GLIBC_2.6 { strerror_l; } + GLIBC_2.23 { + strlcpy; + } } diff --git a/string/bits/string3.h b/string/bits/string3.h index 4d11aa6..9f28a73 100644 --- a/string/bits/string3.h +++ b/string/bits/string3.h @@ -40,6 +40,7 @@ __warndecl (__warn_memset_zero_len, # undef stpcpy # endif # ifdef __USE_MISC +# undef strlcpy # undef bcopy # undef bzero # endif @@ -155,3 +156,29 @@ __NTH (strncat (char *__restrict __dest, const char *__restrict __src, { return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest)); } + +#ifdef __USE_MISC +__warndecl (__warn_strlcpy_size_zero, + "strlcpy used with a size argument of zero"); +__warndecl (__warn_strlcpy_size_large, + "strlcpy used with a size argument which is too large"); +extern size_t __strlcpy_chk (char *__dest, const char *__src, size_t __n, + size_t __destlen) __THROW; + +__fortify_function size_t +__NTH (strlcpy (char *__restrict __dest, const char *__restrict __src, + size_t __len)) +{ + if (__builtin_constant_p (__len == 0) && __len == 0) + { + __warn_strlcpy_size_zero (); + return 0; + } + if (__builtin_constant_p (__len > __bos (__dest)) && __len > __bos (__dest)) + __warn_strlcpy_size_large (); + if (__builtin_constant_p (__bos (__dest) == (size_t) -1) + && __bos (__dest) == (size_t) -1) + return strlcpy (__dest, __src, __len); + return __strlcpy_chk (__dest, __src, __len, __bos (__dest)); +} +#endif diff --git a/string/string.h b/string/string.h index 3ab7103..92a5d80 100644 --- a/string/string.h +++ b/string/string.h @@ -574,6 +574,13 @@ extern char *stpncpy (char *__restrict __dest, __THROW __nonnull ((1, 2)); #endif +#ifdef __USE_MISC +/* Copy at most N characters from SRC to DEST. */ +extern size_t strlcpy (char *__restrict __dest, + const char *__restrict __src, size_t __n) + __THROW __nonnull ((1, 2)); +#endif + #ifdef __USE_GNU /* Compare S1 and S2 as strings holding name & indices/version numbers. */ extern int strverscmp (const char *__s1, const char *__s2) diff --git a/string/strlcpy.c b/string/strlcpy.c new file mode 100644 index 0000000..9b39d86 --- /dev/null +++ b/string/strlcpy.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> + +#undef strlcpy + +size_t +strlcpy(char *__restrict dest, const char *__restrict src, size_t size) +{ + size_t src_length = strlen (src); + + if (__glibc_unlikely (src_length >= size)) + { + if (size > 0) + { + /* Copy the leading portion of the string. The last + character is subsequently overwritten with the NUL + terminator, but the destination size is usually a + multiple of a small power of two, so writing it twice + should be more efficient than copying an odd number of + bytes. */ + memcpy (dest, src, size); + dest[size - 1] = '\0'; + } + } + else + /* Copy the string and its terminating NUL character. */ + memcpy (dest, src, src_length + 1); + return src_length; +} +libc_hidden_def (strlcpy) diff --git a/string/tst-strlcpy.c b/string/tst-strlcpy.c new file mode 100644 index 0000000..016411b --- /dev/null +++ b/string/tst-strlcpy.c @@ -0,0 +1,65 @@ +/* Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#define CHECK(cond) \ + if (!(cond)) \ + { \ + printf ("%s:%d: FAIL\n", __FILE__, __LINE__); \ + exit (1); \ + } + +static int +do_test (void) +{ + struct { + char buf1[16]; + char buf2[16]; + } s; + + memset (&s, '@', sizeof (s)); + CHECK (strlcpy (s.buf1, "Hello!", 0) == 6); + CHECK (memcmp (&s, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", sizeof (s)) == 0); + + memset (&s, '@', sizeof (s)); + CHECK (strlcpy (s.buf1, "Hello!", sizeof (s.buf1)) == 6); + CHECK (memcmp (&s, "Hello!\0@@@@@@@@@@@@@@@@@@@@@@@@@", sizeof (s)) == 0); + + memset (&s, '@', sizeof (s)); + CHECK (strlcpy (s.buf1, "Hello, world!!!", sizeof (s.buf1)) == 15); + CHECK (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", + sizeof (s)) == 0); + + memset (&s, '@', sizeof (s)); + CHECK (strlcpy (s.buf1, "Hello, world!!!!", sizeof (s.buf1)) == 16); + CHECK (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", + sizeof (s)) == 0); + + memset (&s, '@', sizeof (s)); + CHECK (strlcpy (s.buf1, "Hello, world!!!!!!!!", sizeof (s.buf1)) == 20); + CHECK (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", + sizeof (s)) == 0); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + diff --git a/sysdeps/arm/nacl/libc.abilist b/sysdeps/arm/nacl/libc.abilist index 561441e..9137c51 100644 --- a/sysdeps/arm/nacl/libc.abilist +++ b/sysdeps/arm/nacl/libc.abilist @@ -1834,3 +1834,6 @@ GLIBC_2.22 wprintf F GLIBC_2.22 write F GLIBC_2.22 writev F GLIBC_2.22 wscanf F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index c1ba62c..62c6412 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2081,3 +2081,6 @@ GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.18 _mcount F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 7d2d121..e5bff7e 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -1992,6 +1992,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index a30b258..5e7f8e9 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -82,6 +82,9 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 571548a..ff90320 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -1846,6 +1846,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 87abbbd..ecf1d72 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2004,6 +2004,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 1cbdffe..8039f68 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -1868,6 +1868,9 @@ GLIBC_2.2.6 __nanosleep F GLIBC_2.2.6 getunwind F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 061b5ee..8053211 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -83,6 +83,9 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 91be3d8..d3d9863 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -1960,6 +1960,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index c1b1cad..6fe3aeb 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -2081,3 +2081,6 @@ GLIBC_2.18 xprt_register F GLIBC_2.18 xprt_unregister F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 3ef9b99..87de055 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -1935,6 +1935,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index c44ee13..aed7e26 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -1933,6 +1933,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index e8908e4..06d5c94 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -1931,6 +1931,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index c6d1da2..e06e184 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -1926,6 +1926,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 703979a..c837ec4 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2122,3 +2122,6 @@ GLIBC_2.21 xprt_register F GLIBC_2.21 xprt_unregister F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 90ca484..866c0c5 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -1964,6 +1964,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index a5ecc76..2b647f7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -1969,6 +1969,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist index c6bea69..b0359b2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist @@ -2169,3 +2169,6 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index 21e736b..df9a5f5 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist @@ -83,6 +83,9 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 _Exit F GLIBC_2.3 _IO_2_1_stderr_ D 0xe0 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index d6c037b..12528d0 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -1964,6 +1964,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 02422da..99d63b4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -1865,6 +1865,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index 5accb42..5d7baaa 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -1850,6 +1850,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 0ecba65..eda8cc2 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -1956,6 +1956,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index ce45412..9c72aaf 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -1894,6 +1894,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist index 63441e9..50bbb2d 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist @@ -2088,3 +2088,6 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist index 212e4d5..51c87cd 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist @@ -2088,3 +2088,6 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist index 63441e9..50bbb2d 100644 --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist @@ -2088,3 +2088,6 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index afb29dc..60e85dc 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -1845,6 +1845,9 @@ GLIBC_2.2.6 GLIBC_2.2.6 A GLIBC_2.2.6 __nanosleep F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 7ac7104..386d4b3 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2088,3 +2088,6 @@ GLIBC_2.18 GLIBC_2.18 A GLIBC_2.18 __cxa_thread_atexit_impl F GLIBC_2.22 GLIBC_2.22 A GLIBC_2.22 fmemopen F +GLIBC_2.23 GLIBC_2.23 A +GLIBC_2.23 __strlcpy_chk F +GLIBC_2.23 strlcpy F