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]

[PATCH v4] Implement strlcpy [BZ #178]


On 10/29/2015 10:50 PM, 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 want to give any guarantees other implementations do not provide.

> * 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 added a sentence about null-termination just before the comment about
undefined behavior:

The string @var{from} must be null-terminated even if its length exceeds
that of the destination buffer.  The behavior of @code{strlcpy} is
undefined if the strings overlap or if the source or destination are
null pointers.

> * 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 what the patch always has done, the declaration is guarded by
__USE_MISC.

> This is less likely to break existing applications.

We'll see.  Compile-time breakage is one thing, but there could also be
incompatible interposed implementations.  For example, there are
implementations which specify int instead of size_t for the lengths.

> * 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))).

The original OpenBSD implementation does not handle all overlapping
buffers in the same way memmove would.  Most BSDs now specify the
restrict qualify in the function prototype and documentation.

The existing *_chk functions do not check for overlapping inputs, and
they even have restrict pointer arguments, so such checks could be
futile anyway.  If we want to change this approach, I think this should
be a separate discussion.  (Right now, there is memstomp for this.)

>> +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}."

What about this?

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 which null-terminates the destination string as long
as the destination buffer does not have length zero.

> 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."

The submitted patch already had this note directly following the bit you
criticized.

@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.

I think this recommendation is clear enough.

Florian
2015-11-02  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
@@ -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..a13bcfe
--- /dev/null
+++ b/debug/strlcpy_chk.c
@@ -0,0 +1,30 @@
+/* Fortified version of strlcpy.
+   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..8eda29a 100644
--- a/manual/string.texi
+++ b/manual/string.texi
@@ -576,17 +576,52 @@ 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 which null-terminates the destination string as long as the
+destination buffer does not have length zero.
+@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 string @var{from} must be null-terminated even if its length exceeds
+that of the destination buffer.  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..3833a50
--- /dev/null
+++ b/string/strlcpy.c
@@ -0,0 +1,47 @@
+/* Copy a null-terminated string to a fixed-size buffer, with length checking.
+   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..b97f591
--- /dev/null
+++ b/string/tst-strlcpy.c
@@ -0,0 +1,66 @@
+/* Test the strlcpy function.
+   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

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