This change may cause application code not to compile anymore, but
strlcpy is in the implementation namespace (per C11 7.31.13), so this
is an application issue.
2015-11-04 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.
@@ -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.
@@ -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 \
@@ -55,6 +55,9 @@ libc {
GLIBC_2.16 {
__poll_chk; __ppoll_chk;
}
+ GLIBC_2.23 {
+ __strlcpy_chk;
+ }
GLIBC_PRIVATE {
__fortify_fail;
}
new file mode 100644
@@ -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);
+}
@@ -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);
@@ -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)
@@ -576,17 +576,55 @@ 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. Like
+other string functions such as @code{strcpy}, but unlike @code{strncpy},
+the remaining characters in the destination buffer, if any, remain
+unchanged.
+
+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
@@ -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
@@ -80,4 +80,7 @@ libc {
GLIBC_2.6 {
strerror_l;
}
+ GLIBC_2.23 {
+ strlcpy;
+ }
}
@@ -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
@@ -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)
new file mode 100644
@@ -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)
new file mode 100644
@@ -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"
+
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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