[PATCH] Implement strlcpy and strlcat [BZ #178]

Siddhesh Poyarekar siddhesh@gotplt.org
Wed Jun 29 19:30:10 GMT 2022


On 28/06/2022 02:23, Florian Weimer via Libc-alpha wrote:
> These functions are about to be added to POSIX, under Austin Group
> issue 986.

Please note the link in the git commit message to the description you're 
referring to so that it's explicit:

https://www.austingroupbugs.net/view.php?id=986#c4967

> 
> (not for commit message) Tested on i686-linux-gnu and x86_64-linux-gnu.
> Built with build-many-glibcs.py.
> 
> Compared to the previously posted version, I adjusted the symbol
> version, marked the destination buffer as non-null (based on my
> interpretation of the POSIX description), added access attributes, and
> removed the custom warnings code (__warndecl had already been removed).
> If we want additional compiler warnings, they are likely better placed
> in compilers.  The compiler is better placed to issue comprehensible
> warnings, I think.
> 
> Paul, does your previous objection still stand, given that these
> interfaces appear to be heading to an upcoming POSIX version?  I had
> nothing to do with the POSIX decision, so I wasn't trying to undermine
> the glibc consensus procedures.

I'll stick to technical review then, hopefully it'll be useful to 
maintain your patch until the standards issues are resolved.

> diff --git a/NEWS b/NEWS
> index b0a3d7e512..74829a30a6 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -46,6 +46,8 @@ Major new features:
>     to more flexibly configure and operate on filesystem mounts.  The new
>     mount APIs are specifically designed to work with namespaces.
>   
> +* The functions strlcpy and strlcat have been added.
> +
>   Deprecated and removed features, and other changes affecting compatibility:
>   
>   * Support for prelink will be removed in the next release; this includes
> diff --git a/debug/Makefile b/debug/Makefile
> index 456b349c4d..abb0a85b03 100644
> --- a/debug/Makefile
> +++ b/debug/Makefile
> @@ -31,6 +31,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 strlcat_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 a6628db356..a4bfbcfee6 100644
> --- a/debug/Versions
> +++ b/debug/Versions
> @@ -58,6 +58,10 @@ libc {
>     GLIBC_2.25 {
>       __explicit_bzero_chk;
>     }
> +  GLIBC_2.36 {
> +    __strlcpy_chk;
> +    __strlcat_chk;
> +  }
>     GLIBC_PRIVATE {
>       __fortify_fail;
>     }
> diff --git a/debug/strlcat_chk.c b/debug/strlcat_chk.c
> new file mode 100644
> index 0000000000..15e4182229
> --- /dev/null
> +++ b/debug/strlcat_chk.c
> @@ -0,0 +1,32 @@
> +/* Fortified version of strlcat.
> +   Copyright (C) 2017 Free Software Foundation, Inc.

Copyright 2022?  For all files.

> +   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>
> +
> +/* Check that the user-supplied size does not exceed the
> +   compiler-determined size, and then forward to strlcat.  */
> +size_t
> +__strlcat_chk (char *__restrict s1, const char *__restrict s2,
> +	       size_t n, size_t s1len)
> +{
> +  if (__glibc_unlikely (s1len < n))
> +    __chk_fail ();

The manual/string.texi description specifically defines behaviour when n 
 > s1len, so it doesn't make sense to make that case fail for the 
fortified variant.  That or modify the manual to call this usage out as 
problematic (and explicitly specify n as the size of s1) and unsupported 
with fortification.  AFAICT, this hardening then becomes a GNU extension 
since the standard text appears to allow it too.

> +
> +  return strlcat (s1, s2, n);
> +} > diff --git a/debug/strlcpy_chk.c b/debug/strlcpy_chk.c
> new file mode 100644
> index 0000000000..1bcb12b793
> --- /dev/null
> +++ b/debug/strlcpy_chk.c
> @@ -0,0 +1,32 @@
> +/* Fortified version of strlcpy.
> +   Copyright (C) 2017 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>
> +
> +/* Check that the user-supplied size does not exceed the
> +   compiler-determined size, and then forward to strlcpy.  */
> +size_t
> +__strlcpy_chk (char *__restrict s1, const char *__restrict s2,
> +	       size_t n, size_t s1len)
> +{
> +  if (__glibc_unlikely (s1len < n))
> +    __chk_fail ();

Likewise.

> +
> +  return strlcpy (s1, s2, n);
> +}
> diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
> index 8e94643bf2..d4ead37c77 100644
> --- a/debug/tst-fortify.c
> +++ b/debug/tst-fortify.c
> @@ -535,6 +535,16 @@ 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
> +
> +  {
> +    char *volatile buf2 = buf;
> +    if (strlcpy (buf2, "a", sizeof (buf) + 1) != 1)
> +      FAIL ();
> +  }
> +
>   # if !defined __cplusplus || defined __va_arg_pack
>     CHK_FAIL_START
>     sprintf (a.buf1 + (O + 7), "%d", num1);
> @@ -558,6 +568,18 @@ do_test (void)
>     CHK_FAIL_START
>     strncat (a.buf1, "ZYXWV", l0 + 3);
>     CHK_FAIL_END
> +
> +  buf[0] = '\0';
> +  CHK_FAIL_START
> +  strlcat (buf, "ZYXWV", sizeof (buf) + 1);
> +  CHK_FAIL_END
> +
> +  {
> +    buf[0] = '\0';
> +    char *volatile buf2 = buf;
> +    if (strlcat (buf2, "a", sizeof (buf) + 1) != 1)
> +      FAIL ();
> +  }
>   #endif
>   
>   
> diff --git a/include/string.h b/include/string.h
> index 21f641a413..b01b2fb2b4 100644
> --- a/include/string.h
> +++ b/include/string.h
> @@ -91,6 +91,8 @@ libc_hidden_proto (__stpcpy)
>   # define __stpcpy(dest, src) __builtin_stpcpy (dest, src)
>   #endif
>   libc_hidden_proto (__stpncpy)
> +libc_hidden_proto (strlcpy)
> +libc_hidden_proto (strlcat)
>   libc_hidden_proto (__rawmemchr)
>   libc_hidden_proto (__strcasecmp)
>   libc_hidden_proto (__strcasecmp_l)
> diff --git a/manual/string.texi b/manual/string.texi
> index 0b60b3fbb4..c2f4d3b2de 100644
> --- a/manual/string.texi
> +++ b/manual/string.texi
> @@ -1068,6 +1068,76 @@ processing text.  Also, this function has significant performance
>   issues.  @xref{Concatenating Strings}.
>   @end deftypefun
>   
> +@deftypefun size_t strlcpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
> +@standards{BSD, string.h}
> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
> +This function is similar to @code{strcpy}, but copies at most
> +@var{size} bytes from the string @var{from} into the destination
> +array @var{to}, including a terminating null byte.
> +
> +If @var{size} is greater than the length of the string @var{from},
> +this function copies all of the string @var{from} to the destination
> +array @var{to}, including the terminating null byte.  Like other
> +string functions such as @code{strcpy}, but unlike @code{strncpy}, any
> +remaining bytes in the destination array remain unchanged.

The standard wording says copy only up to (but not including) the NUL 
byte.  The NUL byte is added separately:

     The strlcpy() function shall copy not more than dstsize - 1 bytes
     from the string pointed to by src to the array pointed to by dst; a
     NUL byte in src and bytes that follow it shall not be copied.

The difference is only academic I suppose.

> +
> +If @var{size} is nonzero and less than or equal to the the length of the string
> +@var{from}, this function copies only the first @samp{@var{size} - 1}
> +bytes to the destination array @var{to}, and writes a terminating null
> +byte to the last byte of the array.
> +
> +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 @var{size} is zero, or if
> +the source string and the first @var{size} bytes of the destination
> +array overlap.
> +
> +As noted below, this function is generally a poor choice for processing
> +text.  Unlike @code{strncpy}, @code{strlcpy} requires @var{size} to be
> +nonzero and the source string to be null-terminated, computes the
> +source string's length, ensures that the destination is
> +null-terminated, and does not fill the remaining part of the destination
> +with null bytes.
> +
> +This function is derived from OpenBSD 2.4.

Given that we're putting it in to comply with a future POSIX version, 
shouldn't that be mentioned instead of OpenBSD?  Or maybe both?

> +@end deftypefun
> +
> +@deftypefun size_t strlcat (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
> +@standards{BSD, string.h}
> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
> +This function appends the string @var{from} to the
> +string @var{to}, limiting the total size of the result string at
> +@var{to} (including the null terminator) to @var{size}.
> +
> +This function copies as much as possible of the string @var{from} into
> +the array at @var{to} of @var{size} bytes, starting at the terminating
> +null byte of the original string @var{to}.  In effect, this appends
> +the string @var{from} to the string @var{to}.  Although the resulting
> +string will contain a null terminator, it can be truncated (not all
> +bytes in @var{from} may be copied).
> +
> +This function returns the sum of the original length of @var{to} and
> +the length of @var{from}.  This means that truncation occurs unless
> +the returned value is less than @var{size}.

Maybe rephrase it in the positive, e.g.:

     This means that if the returned value is greater than or equal to
     size, the result is truncated.

> +
> +The behavior is undefined if the array at @var{to} does not contain a
> +null byte in its first @var{size} bytes, or if the source string and the
> +first @var{size} bytes of @var{to} overlap.
> +
> +As noted below, this function is generally a poor choice for processing
> +text.  Also, this function has significant performance issues;
> +@pxref{Concatenating Strings}.  Unlike @code{strncat}, @var{size}
> +specifies the maximum total size of the result string (including its
> +null terminator), not the number of bytes copied from the source string
> +@var{from}.  Unlike @code{strncat}, this function requires the source
> +and destination to be null-terminated, computes the source string's
> +length, and keeps the destination null-terminated.
> +
> +This function is derived from OpenBSD 2.4.

Likewise.

> +@end deftypefun
> +
>   Because these functions can abruptly truncate strings or wide strings,
>   they are generally poor choices for processing text.  When coping or
>   concatening multibyte strings, they can truncate within a multibyte
> diff --git a/string/Makefile b/string/Makefile
> index 641e062bbb..5ee11c467c 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -92,6 +92,8 @@ routines := \
>     strerrorname_np \
>     strfry \
>     string-inlines \
> +  strlcat \
> +  strlcpy \
>     strlen \
>     strncase \
>     strncase_l \
> @@ -175,6 +177,8 @@ tests := \
>     tst-inlcall \
>     tst-memmove-overflow \
>     tst-strfry \
> +  tst-strlcat \
> +  tst-strlcpy \
>     tst-strlen \
>     tst-strtok \
>     tst-strtok_r \
> diff --git a/string/Versions b/string/Versions
> index 864c4cf7a4..fbe008c833 100644
> --- a/string/Versions
> +++ b/string/Versions
> @@ -92,4 +92,8 @@ libc {
>     GLIBC_2.35 {
>       __memcmpeq;
>     }
> +  GLIBC_2.36 {
> +    strlcpy;
> +    strlcat;
> +  }
>   }
> diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
> index 149ebbb08b..91240f1d1c 100644
> --- a/string/bits/string_fortified.h
> +++ b/string/bits/string_fortified.h
> @@ -139,4 +139,38 @@ __NTH (strncat (char *__restrict __dest, const char *__restrict __src,
>   				  __glibc_objsize (__dest));
>   }
>   
> +#ifdef __USE_MISC
> +extern size_t __strlcpy_chk (char *__dest, const char *__src, size_t __n,
> +			     size_t __destlen) __THROW;
> +extern size_t __REDIRECT_NTH (__strlcpy_alias,
> +			      (char *__dest, const char *__src, size_t __n),
> +			      strlcpy);
> +
> +__fortify_function size_t
> +__NTH (strlcpy (char *__restrict __dest, const char *__restrict __src,
> +		size_t __len))
> +{
> +  if (__builtin_constant_p (__bos (__dest) == (size_t) -1)
> +      && __bos (__dest) == (size_t) -1)
> +    return __strlcpy_alias (__dest, __src, __len);
> +  return __strlcpy_chk (__dest, __src, __len, __bos (__dest));
> +}
> +
> +extern size_t __strlcat_chk (char *__dest, const char *__src, size_t __n,
> +			     size_t __destlen) __THROW;
> +extern size_t __REDIRECT_NTH (__strlcat_alias,
> +			      (char *__dest, const char *__src, size_t __n),
> +			      strlcat);
> +
> +__fortify_function size_t
> +__NTH (strlcat (char *__restrict __dest, const char *__restrict __src,
> +		size_t __len))
> +{
> +  if (__builtin_constant_p (__bos (__dest) == (size_t) -1)
> +      && __bos (__dest) == (size_t) -1)
> +    return __strlcat_alias (__dest, __src, __len);
> +  return __strlcat_chk (__dest, __src, __len, __bos (__dest));

Maybe use __glibc_fortify?

> +}
> +#endif /* __USE_MISC */
> +
>   #endif /* bits/string_fortified.h */
> diff --git a/string/string.h b/string/string.h
> index 54dd8344de..51241018c3 100644
> --- a/string/string.h
> +++ b/string/string.h
> @@ -501,6 +501,19 @@ extern char *stpncpy (char *__restrict __dest,
>        __THROW __nonnull ((1, 2));
>   #endif
>   
> +#ifdef __USE_MISC
> +/* Copy at most N - 1 characters from SRC to DEST.  */
> +extern size_t strlcpy (char *__restrict __dest,
> +		       const char *__restrict __src, size_t __n)
> +  __THROW __nonnull ((1, 2)) __attr_access ((__write_only__, 1, 3));
> +
> +/* Append SRC to DEST, possibly with truncation to keep the total size
> +   below N.  */
> +extern size_t strlcat (char *__restrict __dest,
> +		       const char *__restrict __src, size_t __n)
> +  __THROW __nonnull ((1, 2))  __attr_access ((__read_write__, 1, 3));
> +#endif
> +

The __attr_access will result in a warning if size of dst is smaller 
than dstsize (i.e. argument 3).  Like the _chk variant case, it doesn't 
match with the manual.

>   #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/strlcat.c b/string/strlcat.c
> new file mode 100644
> index 0000000000..297923ad9b
> --- /dev/null
> +++ b/string/strlcat.c
> @@ -0,0 +1,60 @@
> +/* Append a null-terminated string to another string, with length checking.
> +   Copyright (C) 2017 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 <stdint.h>
> +#include <string.h>
> +
> +#undef strlcat
> +
> +size_t
> +strlcat (char *__restrict dest, const char *__restrict src, size_t size)
> +{
> +  size_t src_length = strlen (src);
> +
> +  /* Our implementation strlcat supports dest == NULL if size == 0

Does it though?  The header specifies __nonnull (1, 2), which should 
warn on NUL input.  Maybe this needs test coverage.

> +     (for consistency with snprintf and strlcpy), but strnlen does
> +     not, so we have to cover this case explicitly.  */
> +  if (size == 0)
> +    return src_length;
> +
> +  size_t dest_length = __strnlen (dest, size);

dst is allowed to be a string in strlcat.  OK.

> +  if (dest_length != size)
> +    {
> +      /* Copy at most the remaining number of characters in the
> +	 destination buffer.  Leave for the NUL terminator.  */
> +      size_t to_copy = size - dest_length - 1;

Implicit assumption that size - 1 > dest_length.  I suppose the wording 
allows it.

> +      /* But not more than what is available in the source string.  */
> +      if (to_copy > src_length)
> +	to_copy = src_length;
> +
> +      char *target = dest + dest_length;
> +      memcpy (target, src, to_copy);
> +      target[to_copy] = '\0';

Overwrites the NUL at the end of dest, copies without the NUL and then 
writes the NUL at the end.  OK.

> +    }
> +
> +  /* If the sum wraps around, we have more than SIZE_MAX + 2 bytes in
> +     the two input strings (including both null terminators).  If each
> +     byte in the address space can be assigned a unique size_t value
> +     (which the static_assert checks), then by the pigeonhole
> +     principle, the two input strings must overlap, which is
> +     undefined.  */
> +  _Static_assert (sizeof (uintptr_t) == sizeof (size_t),
> +		  "theoretical maximum object size covers address space");
> +  return dest_length + src_length;
> +}
> +libc_hidden_def (strlcat)
> diff --git a/string/strlcpy.c b/string/strlcpy.c
> new file mode 100644
> index 0000000000..d0764e9b64
> --- /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) 2017 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.  */

That's not necessary for all arches, but it's too early to talk of 
micro-optimization so whatever you choose is fine I think.

> +	  memcpy (dest, src, size);
> +	  dest[size - 1] = '\0';
> +	}
> +    }
> +  else
> +    /* Copy the string and its terminating NUL character.  */
> +    memcpy (dest, src, src_length + 1);

Going by POSIX wording, it should copy src_length and *write* the last 
NUL, not copy it from src.  Only an academic difference again.  That 
said though, you could just collapse the whole thing to:

if (size > 0)
   {
     size_t n = src_length >= size ? size - 1 : src_length;
     memcpy (dest, src, n);
     dest[n] = '\0';
   }

and then tune it later based on workloads and architectures.

> +  return src_length;
> +}
> +libc_hidden_def (strlcpy)
> diff --git a/string/tst-strlcat.c b/string/tst-strlcat.c
> new file mode 100644
> index 0000000000..805524754a
> --- /dev/null
> +++ b/string/tst-strlcat.c
> @@ -0,0 +1,90 @@
> +/* Test the strlcat function.
> +   Copyright (C) 2017 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>
> +#include <support/check.h>
> +
> +static int
> +do_test (void)
> +{
> +  struct {
> +    char buf1[16];
> +    char buf2[16];
> +  } s;
> +
> +  /* Nothing is written to the destination if its size is 0.  */
> +  memset (&s, '@', sizeof (s));
> +  TEST_VERIFY (strlcat (s.buf1, "", 0) == 0);
> +  TEST_VERIFY (memcmp (&s, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +  TEST_VERIFY (strlcat (s.buf1, "Hello!", 0) == 6);
> +  TEST_VERIFY (memcmp (&s, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  /* No bytes are are modified in the target buffer if the source
> +     string is short enough.  */
> +  memset (&s, '@', sizeof (s));
> +  strcpy (s.buf1, "He");
> +  TEST_VERIFY (strlcat (s.buf1, "llo!", sizeof (s.buf1)) == 6);
> +  TEST_VERIFY (memcmp (&s, "Hello!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  /* A source string which fits exactly into the destination buffer is
> +     not truncated.  */
> +  memset (&s, '@', sizeof (s));
> +  strcpy (s.buf1, "H");
> +  TEST_VERIFY (strlcat (s.buf1, "ello, world!!!", sizeof (s.buf1)) == 15);
> +  TEST_VERIFY (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		 sizeof (s)) == 0);
> +
> +  /* A source string one character longer than the destination buffer
> +     is truncated by one character.  The total length is returned.  */
> +  memset (&s, '@', sizeof (s));
> +  strcpy (s.buf1, "Hello");
> +  TEST_VERIFY (strlcat (s.buf1, ", world!!!!", sizeof (s.buf1)) == 16);
> +  TEST_VERIFY (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		 sizeof (s)) == 0);
> +
> +  /* An even longer source string is truncated as well, and the total
> +     length is returned.  */
> +  memset (&s, '@', sizeof (s));
> +  strcpy (s.buf1, "Hello,");
> +  TEST_VERIFY (strlcat (s.buf1, " world!!!!!!!!", sizeof (s.buf1)) == 20);
> +  TEST_VERIFY (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		 sizeof (s)) == 0);
> +
> +  /* A destination string which is not NUL-terminated does not result
> +     in any changes to the buffer.  */
> +  memset (&s, '@', sizeof (s));
> +  memset (s.buf1, '$', sizeof (s.buf1));
> +  TEST_VERIFY (strlcat (s.buf1, "", sizeof (s.buf1)) == 16);
> +  TEST_VERIFY (memcmp (&s, "$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +  TEST_VERIFY (strlcat (s.buf1, "Hello!", sizeof (s.buf1)) == 22);
> +  TEST_VERIFY (memcmp (&s, "$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +  TEST_VERIFY (strlcat (s.buf1, "Hello, world!!!!!!!!", sizeof (s.buf1)) == 36);
> +  TEST_VERIFY (memcmp (&s, "$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/string/tst-strlcpy.c b/string/tst-strlcpy.c
> new file mode 100644
> index 0000000000..16bc75c067
> --- /dev/null
> +++ b/string/tst-strlcpy.c
> @@ -0,0 +1,70 @@
> +/* Test the strlcpy function.
> +   Copyright (C) 2017 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>
> +#include <support/check.h>
> +
> +static int
> +do_test (void)
> +{
> +  struct {
> +    char buf1[16];
> +    char buf2[16];
> +  } s;
> +
> +  /* Nothing is written to the destination if its size is 0.  */
> +  memset (&s, '@', sizeof (s));
> +  TEST_VERIFY (strlcpy (s.buf1, "Hello!", 0) == 6);
> +  TEST_VERIFY (memcmp (&s, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  /* No bytes are are modified in the target buffer if the source
> +     string is short enough.  */
> +  memset (&s, '@', sizeof (s));
> +  TEST_VERIFY (strlcpy (s.buf1, "Hello!", sizeof (s.buf1)) == 6);
> +  TEST_VERIFY (memcmp (&s, "Hello!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  /* A source string which fits exactly into the destination buffer is
> +     not truncated.  */
> +  memset (&s, '@', sizeof (s));
> +  TEST_VERIFY (strlcpy (s.buf1, "Hello, world!!!", sizeof (s.buf1)) == 15);
> +  TEST_VERIFY (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  /* A source string one character longer than the destination buffer
> +     is truncated by one character.  The untruncated source length is
> +     returned.  */
> +  memset (&s, '@', sizeof (s));
> +  TEST_VERIFY (strlcpy (s.buf1, "Hello, world!!!!", sizeof (s.buf1)) == 16);
> +  TEST_VERIFY (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  /* An even longer source string is truncated as well, and the
> +     original length is returned.  */
> +  memset (&s, '@', sizeof (s));
> +  TEST_VERIFY (strlcpy (s.buf1, "Hello, world!!!!!!!!", sizeof (s.buf1)) == 20);
> +  TEST_VERIFY (memcmp (&s, "Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@",
> +		       sizeof (s)) == 0);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 4dc87e9061..57ab83842f 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2289,6 +2289,10 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 close_range F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 8dba065b81..79593721f7 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2616,6 +2616,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2624,3 +2626,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 08f4750022..8e1588e0a6 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2713,6 +2713,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2721,6 +2723,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _IO_fprintf F
>   GLIBC_2.4 _IO_printf F
>   GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> index 75db763023..589f32ef7d 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> @@ -2377,6 +2377,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2385,3 +2387,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index fa33f317ac..66aad3e945 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -496,6 +496,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -504,6 +506,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _Exit F
>   GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
>   GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index dba2e4ce42..da3a1bce34 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -493,6 +493,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -501,6 +503,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _Exit F
>   GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
>   GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index e6ff921c29..c2ea825539 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2652,6 +2652,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2660,3 +2662,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 8a40cece83..4859a686a6 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2601,6 +2601,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2609,6 +2611,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index a89826049f..2547999a77 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2785,6 +2785,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2793,6 +2795,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index d1d96b7469..a8c73d31f6 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2551,6 +2551,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2559,6 +2561,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 63a62f267a..0f419bfd22 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -497,6 +497,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -505,6 +507,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _Exit F
>   GLIBC_2.4 _IO_2_1_stderr_ D 0x98
>   GLIBC_2.4 _IO_2_1_stdin_ D 0x98
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index f68325f9bc..aa6332040f 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2728,6 +2728,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2736,6 +2738,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 247af2075c..ab63dbacd6 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2701,6 +2701,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2709,3 +2711,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index b0ac3f9009..4f55786882 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2698,6 +2698,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2706,3 +2708,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 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 b22cd6bf2f..44d5c4e115 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2693,6 +2693,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2701,6 +2703,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 12fc2cce3e..cf8f7690fd 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2691,6 +2691,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2699,6 +2701,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index d3e96dfd43..1ee70f2e2a 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2699,6 +2699,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2707,6 +2709,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index cb58ed4db0..99ec7125af 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2602,6 +2602,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2610,6 +2612,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 61ad58a599..98be295843 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2740,6 +2740,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2748,3 +2750,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> index 1260dc4e2e..dc368582af 100644
> --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> @@ -2123,6 +2123,8 @@ GLIBC_2.35 wprintf F
>   GLIBC_2.35 write F
>   GLIBC_2.35 writev F
>   GLIBC_2.35 wscanf F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2131,3 +2133,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 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 363939762c..f5f8a57079 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2755,6 +2755,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2763,6 +2765,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _IO_fprintf F
>   GLIBC_2.4 _IO_printf F
>   GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index f512ad8baf..396c5b7ae0 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2788,6 +2788,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2796,6 +2798,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _IO_fprintf F
>   GLIBC_2.4 _IO_printf F
>   GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index c9bdc9859c..523e01c0ca 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2510,6 +2510,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2518,6 +2520,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _IO_fprintf F
>   GLIBC_2.4 _IO_printf F
>   GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index f091be30bd..0c412e3072 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2812,6 +2812,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2820,3 +2822,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> index 7ea73f9af8..3703c33c07 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> @@ -2379,6 +2379,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2387,3 +2389,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 333fa62714..9a719fdfe3 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2579,6 +2579,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2587,3 +2589,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index a867467b12..5f05b253d5 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2753,6 +2753,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2761,6 +2763,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _IO_fprintf F
>   GLIBC_2.4 _IO_printf F
>   GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index dbad5b3163..36e78d7cb2 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2547,6 +2547,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2555,6 +2557,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _IO_fprintf F
>   GLIBC_2.4 _IO_printf F
>   GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index 6f755cc173..6ccdc54d27 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2608,6 +2608,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2616,6 +2618,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 77d936aa3c..647834425f 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2605,6 +2605,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2613,6 +2615,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 09bb4363e1..fe16974926 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2748,6 +2748,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2756,6 +2758,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 _IO_fprintf F
>   GLIBC_2.4 _IO_printf F
>   GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 9df9cb6adb..f661ba5b4a 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2574,6 +2574,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2582,6 +2584,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 4829450ad0..e170c64b77 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2525,6 +2525,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2533,6 +2535,8 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
>   GLIBC_2.4 __confstr_chk F
>   GLIBC_2.4 __fgets_chk F
>   GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index caea228bcb..8c4cefcb09 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2631,6 +2631,8 @@ GLIBC_2.35 __memcmpeq F
>   GLIBC_2.35 _dl_find_object F
>   GLIBC_2.35 epoll_pwait2 F
>   GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 __strlcat_chk F
> +GLIBC_2.36 __strlcpy_chk F
>   GLIBC_2.36 fsmount F
>   GLIBC_2.36 fsopen F
>   GLIBC_2.36 move_mount F
> @@ -2639,3 +2641,5 @@ GLIBC_2.36 pidfd_open F
>   GLIBC_2.36 pidfd_send_signal F
>   GLIBC_2.36 process_madvise F
>   GLIBC_2.36 process_mrelease F
> +GLIBC_2.36 strlcat F
> +GLIBC_2.36 strlcpy F
> 



More information about the Libc-alpha mailing list