diff options
49 files changed, 711 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog index d15b06d668..1d93077dcd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,62 @@ +2016-12-16 Zack Weinberg <zackw@panix.com> + Florian Weimer <fweimer@redhat.com> + Nick Mathewson <nickm@torproject.org> + + * string/explicit_bzero.c: New routine. + * string/test-explicit_bzero.c, string/tst-xbzero-opt.c: New tests. + * string/Makefile (routines, strop-tests, tests): Add them. + * string/test-memset.c: Add ifdeffage for testing explicit_bzero. + * string/string.h [__USE_MISC]: Declare explicit_bzero. + + * debug/explicit_bzero_chk.c: New routine. + * debug/Makefile (routines): Add it. + * debug/tst-chk1.c: Test fortification of explicit_bzero. + * string/bits/string3.h: Fortify explicit_bzero. + + * manual/string.texi: Document explicit_bzero. + * NEWS: Mention addition of explicit_bzero. + + * crypt/crypt-entry.c (__crypt_r): Clear key-dependent intermediate + data before returning, using explicit_bzero. + * crypt/md5-crypt.c (__md5_crypt_r): Likewise. + * crypt/sha256-crypt.c (__sha256_crypt_r): Likewise. + * crypt/sha512-crypt.c (__sha512_crypt_r): Likewise. + + * include/string.h: Redirect internal uses of explicit_bzero + to __explicit_bzero_chk[_internal]. + * string/Versions [GLIBC_2.25]: Add explicit_bzero. + * debug/Versions [GLIBC_2.25]: Add __explicit_bzero_chk. + * sysdeps/arm/nacl/libc.abilist + * sysdeps/unix/sysv/linux/aarch64/libc.abilist + * sysdeps/unix/sysv/linux/alpha/libc.abilist + * sysdeps/unix/sysv/linux/arm/libc.abilist + * sysdeps/unix/sysv/linux/hppa/libc.abilist + * sysdeps/unix/sysv/linux/i386/libc.abilist + * sysdeps/unix/sysv/linux/ia64/libc.abilist + * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist + * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist + * sysdeps/unix/sysv/linux/microblaze/libc.abilist + * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist + * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist + * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist + * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist + * sysdeps/unix/sysv/linux/nios2/libc.abilist + * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist + * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist + * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist + * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist + * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist + * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist + * sysdeps/unix/sysv/linux/sh/libc.abilist + * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist + * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist + * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist + * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist + * sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist + * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist + * sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: + Add entries for explicit_bzero and __explicit_bzero_chk. + 2016-12-16 Joseph Myers <joseph@codesourcery.com> * math/fenv.h diff --git a/NEWS b/NEWS index baf46bd4ad..43d4e300b2 100644 --- a/NEWS +++ b/NEWS @@ -84,6 +84,12 @@ Version 2.25 * The functions strfromd, strfromf, and strfroml, from ISO/IEC TS 18661-1:2014, are added to libc. They convert a floating-point number into string. +* The function explicit_bzero, from OpenBSD, has been added to libc. It is + intended to be used instead of memset() to erase sensitive data after use; + the compiler will not optimize out calls to explicit_bzero even if they + are "unnecessary" (in the sense that no _correct_ program can observe the + effects of the memory clear). + * On ColdFire, MicroBlaze, Nios II and SH3, the float_t type is now defined to float instead of double. This does not affect the ABI of any libraries that are part of the GNU C Library, but may affect the ABI of other diff --git a/crypt/crypt-entry.c b/crypt/crypt-entry.c index a7dfccaa36..23e776fb9e 100644 --- a/crypt/crypt-entry.c +++ b/crypt/crypt-entry.c @@ -141,6 +141,15 @@ __crypt_r (const char *key, const char *salt, * And convert back to 6 bit ASCII */ _ufc_output_conversion_r (res[0], res[1], salt, data); + + /* + * Erase key-dependent intermediate data. Data dependent only on + * the salt is not considered sensitive. + */ + explicit_bzero (ktab, sizeof (ktab)); + explicit_bzero (data->keysched, sizeof (data->keysched)); + explicit_bzero (res, sizeof (res)); + return data->crypt_3_buf; } weak_alias (__crypt_r, crypt_r) diff --git a/crypt/md5-crypt.c b/crypt/md5-crypt.c index 2243bc7aed..6125c7f7f2 100644 --- a/crypt/md5-crypt.c +++ b/crypt/md5-crypt.c @@ -288,13 +288,13 @@ __md5_crypt_r (const char *key, const char *salt, char *buffer, int buflen) #ifndef USE_NSS __md5_init_ctx (&ctx); __md5_finish_ctx (&ctx, alt_result); - memset (&ctx, '\0', sizeof (ctx)); - memset (&alt_ctx, '\0', sizeof (alt_ctx)); + explicit_bzero (&ctx, sizeof (ctx)); + explicit_bzero (&alt_ctx, sizeof (alt_ctx)); #endif if (copied_key != NULL) - memset (copied_key, '\0', key_len); + explicit_bzero (copied_key, key_len); if (copied_salt != NULL) - memset (copied_salt, '\0', salt_len); + explicit_bzero (copied_salt, salt_len); free (free_key); return buffer; diff --git a/crypt/sha256-crypt.c b/crypt/sha256-crypt.c index d768234879..8c670ea405 100644 --- a/crypt/sha256-crypt.c +++ b/crypt/sha256-crypt.c @@ -371,16 +371,16 @@ __sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen) #ifndef USE_NSS __sha256_init_ctx (&ctx); __sha256_finish_ctx (&ctx, alt_result); - memset (&ctx, '\0', sizeof (ctx)); - memset (&alt_ctx, '\0', sizeof (alt_ctx)); + explicit_bzero (&ctx, sizeof (ctx)); + explicit_bzero (&alt_ctx, sizeof (alt_ctx)); #endif - memset (temp_result, '\0', sizeof (temp_result)); - memset (p_bytes, '\0', key_len); - memset (s_bytes, '\0', salt_len); + explicit_bzero (temp_result, sizeof (temp_result)); + explicit_bzero (p_bytes, key_len); + explicit_bzero (s_bytes, salt_len); if (copied_key != NULL) - memset (copied_key, '\0', key_len); + explicit_bzero (copied_key, key_len); if (copied_salt != NULL) - memset (copied_salt, '\0', salt_len); + explicit_bzero (copied_salt, salt_len); free (free_key); free (free_pbytes); diff --git a/crypt/sha512-crypt.c b/crypt/sha512-crypt.c index f404c88b20..dac145b2e9 100644 --- a/crypt/sha512-crypt.c +++ b/crypt/sha512-crypt.c @@ -393,16 +393,16 @@ __sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen) #ifndef USE_NSS __sha512_init_ctx (&ctx); __sha512_finish_ctx (&ctx, alt_result); - memset (&ctx, '\0', sizeof (ctx)); - memset (&alt_ctx, '\0', sizeof (alt_ctx)); + explicit_bzero (&ctx, sizeof (ctx)); + explicit_bzero (&alt_ctx, sizeof (alt_ctx)); #endif - memset (temp_result, '\0', sizeof (temp_result)); - memset (p_bytes, '\0', key_len); - memset (s_bytes, '\0', salt_len); + explicit_bzero (temp_result, sizeof (temp_result)); + explicit_bzero (p_bytes, key_len); + explicit_bzero (s_bytes, salt_len); if (copied_key != NULL) - memset (copied_key, '\0', key_len); + explicit_bzero (copied_key, key_len); if (copied_salt != NULL) - memset (copied_salt, '\0', salt_len); + explicit_bzero (copied_salt, salt_len); free (free_key); free (free_pbytes); diff --git a/debug/Makefile b/debug/Makefile index 6b5f31e4f6..84d3f92c0d 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -48,6 +48,7 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \ vdprintf_chk obprintf_chk \ longjmp_chk ____longjmp_chk \ fdelt_chk poll_chk ppoll_chk \ + explicit_bzero_chk \ stack_chk_fail fortify_fail \ $(static-only-routines) static-only-routines := warning-nop stack_chk_fail_local diff --git a/debug/Versions b/debug/Versions index 0482c85f19..a6628db356 100644 --- a/debug/Versions +++ b/debug/Versions @@ -55,6 +55,9 @@ libc { GLIBC_2.16 { __poll_chk; __ppoll_chk; } + GLIBC_2.25 { + __explicit_bzero_chk; + } GLIBC_PRIVATE { __fortify_fail; } diff --git a/debug/explicit_bzero_chk.c b/debug/explicit_bzero_chk.c new file mode 100644 index 0000000000..2e507f8297 --- /dev/null +++ b/debug/explicit_bzero_chk.c @@ -0,0 +1,44 @@ +/* Generic implementation of __explicit_bzero_chk. + Copyright (C) 1991-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + 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/>. */ + +/* This is the generic definition of __explicit_bzero_chk. The + __explicit_bzero_chk symbol is used as the implementation of + explicit_bzero throughout glibc. If this file is overriden by an + architecture, both __explicit_bzero_chk and + __explicit_bzero_chk_internal have to be defined (the latter not as + an IFUNC). */ + +#include <string.h> + +void +__explicit_bzero_chk (void *dst, size_t len, size_t dstlen) +{ + /* Inline __memset_chk to avoid a PLT reference to __memset_chk. */ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + memset (dst, '\0', len); + /* Compiler barrier. */ + asm volatile ("" ::: "memory"); +} + +/* libc-internal references use the hidden + __explicit_bzero_chk_internal symbol. This is necessary if + __explicit_bzero_chk is implemented as an IFUNC because some + targets do not support hidden references to IFUNC symbols. */ +strong_alias (__explicit_bzero_chk, __explicit_bzero_chk_internal) diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c index 478c2fbb81..e87a279fb2 100644 --- a/debug/tst-chk1.c +++ b/debug/tst-chk1.c @@ -160,6 +160,10 @@ do_test (void) if (memcmp (buf, "aabcdabc\0\0", 10)) FAIL (); + explicit_bzero (buf + 6, 4); + if (memcmp (buf, "aabcda\0\0\0\0", 10)) + FAIL (); + strcpy (buf + 4, "EDCBA"); if (memcmp (buf, "aabcEDCBA", 10)) FAIL (); @@ -201,6 +205,10 @@ do_test (void) if (memcmp (buf, "aabcdabc\0\0", 10)) FAIL (); + explicit_bzero (buf + 6, l0 + 4); + if (memcmp (buf, "aabcda\0\0\0\0", 10)) + FAIL (); + strcpy (buf + 4, str1 + 5); if (memcmp (buf, "aabcEDCBA", 10)) FAIL (); @@ -256,6 +264,10 @@ do_test (void) if (memcmp (a.buf1, "aabcdabc\0\0", 10)) FAIL (); + explicit_bzero (a.buf1 + 6, l0 + 4); + if (memcmp (a.buf1, "aabcda\0\0\0\0", 10)) + FAIL (); + #if __USE_FORTIFY_LEVEL < 2 /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2 and sufficient GCC support, as the string operations overflow @@ -346,6 +358,14 @@ do_test (void) CHK_FAIL_END CHK_FAIL_START + explicit_bzero (buf + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (buf + 9, l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START strcpy (buf + 5, str1 + 5); CHK_FAIL_END @@ -454,6 +474,14 @@ do_test (void) bzero (a.buf1 + 9, l0 + 2); CHK_FAIL_END + CHK_FAIL_START + explicit_bzero (a.buf1 + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (a.buf1 + 9, l0 + 2); + CHK_FAIL_END + # if __USE_FORTIFY_LEVEL >= 2 # define O 0 # else diff --git a/include/string.h b/include/string.h index e145bfdb4c..300a2e2faa 100644 --- a/include/string.h +++ b/include/string.h @@ -100,6 +100,17 @@ extern __typeof (memmem) __memmem; libc_hidden_proto (__memmem) libc_hidden_proto (__ffs) +#if IS_IN (libc) +/* Avoid hidden reference to IFUNC symbol __explicit_bzero_chk. */ +void __explicit_bzero_chk_internal (void *, size_t, size_t) + __THROW __nonnull ((1)) attribute_hidden; +# define explicit_bzero(buf, len) \ + __explicit_bzero_chk_internal (buf, len, __bos0 (buf)) +#elif !IS_IN (nonlib) +void __explicit_bzero_chk (void *, size_t, size_t) __THROW __nonnull ((1)); +# define explicit_bzero(buf, len) __explicit_bzero_chk (buf, len, __bos0 (buf)) +#endif + libc_hidden_builtin_proto (memchr) libc_hidden_builtin_proto (memcpy) libc_hidden_builtin_proto (mempcpy) diff --git a/manual/string.texi b/manual/string.texi index 1986357ee8..b8810d66b7 100644 --- a/manual/string.texi +++ b/manual/string.texi @@ -34,6 +34,8 @@ too. * Search Functions:: Searching for a specific element or substring. * Finding Tokens in a String:: Splitting a string into tokens by looking for delimiters. +* Erasing Sensitive Data:: Clearing memory which contains sensitive + data, after it's no longer needed. * strfry:: Function for flash-cooking a string. * Trivial Encryption:: Obscuring data. * Encode Binary Data:: Encoding and Decoding of Binary Data. @@ -2404,6 +2406,103 @@ contains no '/' bytes, then "." is returned. The prototype for this function can be found in @file{libgen.h}. @end deftypefun +@node Erasing Sensitive Data +@section Erasing Sensitive Data + +Sensitive data, such as cryptographic keys, should be erased from +memory after use, to reduce the risk that a bug will expose it to the +outside world. However, compiler optimizations may determine that an +erasure operation is ``unnecessary,'' and remove it from the generated +code, because no @emph{correct} program could access the variable or +heap object containing the sensitive data after it's deallocated. +Since erasure is a precaution against bugs, this optimization is +inappropriate. + +The function @code{explicit_bzero} erases a block of memory, and +guarantees that the compiler will not remove the erasure as +``unnecessary.'' + +@smallexample +@group +#include <string.h> + +extern void encrypt (const char *key, const char *in, + char *out, size_t n); +extern void genkey (const char *phrase, char *key); + +void encrypt_with_phrase (const char *phrase, const char *in, + char *out, size_t n) +@{ + char key[16]; + genkey (phrase, key); + encrypt (key, in, out, n); + explicit_bzero (key, 16); +@} +@end group +@end smallexample + +@noindent +In this example, if @code{memset}, @code{bzero}, or a hand-written +loop had been used, the compiler might remove them as ``unnecessary.'' + +@strong{Warning:} @code{explicit_bzero} does not guarantee that +sensitive data is @emph{completely} erased from the computer's memory. +There may be copies in temporary storage areas, such as registers and +``scratch'' stack space; since these are invisible to the source code, +a library function cannot erase them. + +Also, @code{explicit_bzero} only operates on RAM. If a sensitive data +object never needs to have its address taken other than to call +@code{explicit_bzero}, it might be stored entirely in CPU registers +@emph{until} the call to @code{explicit_bzero}. Then it will be +copied into RAM, the copy will be erased, and the original will remain +intact. Data in RAM is more likely to be exposed by a bug than data +in registers, so this creates a brief window where the data is at +greater risk of exposure than it would have been if the program didn't +try to erase it at all. + +Declaring sensitive variables as @code{volatile} will make both the +above problems @emph{worse}; a @code{volatile} variable will be stored +in memory for its entire lifetime, and the compiler will make +@emph{more} copies of it than it would otherwise have. Attempting to +erase a normal variable ``by hand'' through a +@code{volatile}-qualified pointer doesn't work at all---because the +variable itself is not @code{volatile}, some compilers will ignore the +qualification on the pointer and remove the erasure anyway. + +Having said all that, in most situations, using @code{explicit_bzero} +is better than not using it. At present, the only way to do a more +thorough job is to write the entire sensitive operation in assembly +language. We anticipate that future compilers will recognize calls to +@code{explicit_bzero} and take appropriate steps to erase all the +copies of the affected data, whereever they may be. + +@comment string.h +@comment BSD +@deftypefun void explicit_bzero (void *@var{block}, size_t @var{len}) +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + +@code{explicit_bzero} writes zero into @var{len} bytes of memory +beginning at @var{block}, just as @code{bzero} would. The zeroes are +always written, even if the compiler could determine that this is +``unnecessary'' because no correct program could read them back. + +@strong{Note:} The @emph{only} optimization that @code{explicit_bzero} +disables is removal of ``unnecessary'' writes to memory. The compiler +can perform all the other optimizations that it could for a call to +@code{memset}. For instance, it may replace the function call with +inline memory writes, and it may assume that @var{block} cannot be a +null pointer. + +@strong{Portability Note:} This function first appeared in OpenBSD 5.5 +and has not been standardized. Other systems may provide the same +functionality under a different name, such as @code{explicit_memset}, +@code{memset_s}, or @code{SecureZeroMemory}. + +@Theglibc{} declares this function in @file{string.h}, but on other +systems it may be in @file{strings.h} instead. +@end deftypefun + @node strfry @section strfry diff --git a/string/Makefile b/string/Makefile index 69d3f802fb..9a8b46d1bf 100644 --- a/string/Makefile +++ b/string/Makefile @@ -41,20 +41,21 @@ 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 explicit_bzero strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ strlen strncmp strncpy strpbrk strrchr strspn memmem \ strstr strcasestr strnlen strcasecmp strncasecmp \ - strncat rawmemchr strchrnul bcopy bzero memrchr + strncat rawmemchr strchrnul bcopy bzero memrchr \ + explicit_bzero tests := tester inl-tester noinl-tester testcopy test-ffs \ tst-strlen stratcliff tst-svc tst-inlcall \ bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \ 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-cmp + tst-strtok_r bug-strcoll2 tst-cmp tst-xbzero-opt xtests = tst-strcoll-overflow diff --git a/string/Versions b/string/Versions index 475c1fdb64..9b709d12a9 100644 --- a/string/Versions +++ b/string/Versions @@ -82,4 +82,7 @@ libc { } GLIBC_2.24 { } + GLIBC_2.25 { + explicit_bzero; + } } diff --git a/string/bits/string3.h b/string/bits/string3.h index 8f13b65fa6..940c8d8e24 100644 --- a/string/bits/string3.h +++ b/string/bits/string3.h @@ -102,6 +102,15 @@ __NTH (bzero (void *__dest, size_t __len)) { (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest)); } + +void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen) + __THROW __nonnull ((1)); + +__fortify_function void +__NTH (explicit_bzero (void *__dest, size_t __len)) +{ + __explicit_bzero_chk (__dest, __len, __bos0 (__dest)); +} #endif __fortify_function char * diff --git a/string/explicit_bzero.c b/string/explicit_bzero.c new file mode 100644 index 0000000000..6712cad5a6 --- /dev/null +++ b/string/explicit_bzero.c @@ -0,0 +1,38 @@ +/* Erasure of sensitive data, generic implementation. + Copyright (C) 2016 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/>. */ + +/* An assembler implementation of explicit_bzero can be created as an + assembler alias of an optimized bzero implementation. + Architecture-specific implementations also need to define + __explicit_bzero_chk. */ + +#include <string.h> + +/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero + redirects to that. */ +#undef explicit_bzero + +/* Set LEN bytes of S to 0. The compiler will not delete a call to + this function, even if S is dead after the call. */ +void +explicit_bzero (void *s, size_t len) +{ + memset (s, '\0', len); + /* Compiler barrier. */ + asm volatile ("" ::: "memory"); +} diff --git a/string/string.h b/string/string.h index b103e64912..c398569c15 100644 --- a/string/string.h +++ b/string/string.h @@ -453,6 +453,10 @@ extern void bcopy (const void *__src, void *__dest, size_t __n) /* Set N bytes of S to 0. */ extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1)); +/* As bzero, but the compiler will not delete a call to this + function, even if S is dead after the call. */ +extern void explicit_bzero (void *__s, size_t __n) __THROW __nonnull ((1)); + /* Compare N bytes of S1 and S2 (same as memcmp). */ extern int bcmp (const void *__s1, const void *__s2, size_t __n) __THROW __attribute_pure__ __nonnull ((1, 2)); diff --git a/string/test-explicit_bzero.c b/string/test-explicit_bzero.c new file mode 100644 index 0000000000..5a4543b41a --- /dev/null +++ b/string/test-explicit_bzero.c @@ -0,0 +1,20 @@ +/* Test and measure explicit_bzero. + Copyright (C) 2016 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/>. */ +#define TEST_EXPLICIT_BZERO +#define TEST_BZERO +#include "test-memset.c" diff --git a/string/test-memset.c b/string/test-memset.c index fee3bdf37f..7ca4f2076c 100644 --- a/string/test-memset.c +++ b/string/test-memset.c @@ -19,7 +19,11 @@ #define TEST_MAIN #ifdef TEST_BZERO -# define TEST_NAME "bzero" +# ifdef TEST_EXPLICIT_BZERO +# define TEST_NAME "explicit_bzero" +# else +# define TEST_NAME "bzero" +# endif #else # ifndef WIDE # define TEST_NAME "memset" @@ -56,7 +60,11 @@ void builtin_bzero (char *, size_t); IMPL (simple_bzero, 0) IMPL (builtin_bzero, 0) +#ifdef TEST_EXPLICIT_BZERO +IMPL (explicit_bzero, 1) +#else IMPL (bzero, 1) +#endif void simple_bzero (char *s, size_t n) diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c new file mode 100644 index 0000000000..312857e056 --- /dev/null +++ b/string/tst-xbzero-opt.c @@ -0,0 +1,288 @@ +/* Test that explicit_bzero block clears are not optimized out. + Copyright (C) 2016 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/>. */ + +/* This test is conceptually based on a test designed by Matthew + Dempsky for the OpenBSD regression suite: + <openbsd>/src/regress/lib/libc/explicit_bzero/explicit_bzero.c. + The basic idea is, we have a function that contains a + block-clearing operation (not necessarily explicit_bzero), after + which the block is dead, in the compiler-jargon sense. Execute + that function while running on a user-allocated alternative + stack. Then we have another pointer to the memory region affected + by the block clear -- namely, the original allocation for the + alternative stack -- and can find out whether it actually happened. + + The OpenBSD test uses sigaltstack and SIGUSR1 to get onto an + alternative stack. This causes a number of awkward problems; some + operating systems (e.g. Solaris and OSX) wipe the signal stack upon + returning to the normal stack, there's no way to be sure that other + processes running on the same system will not interfere, and the + signal stack is very small so it's not safe to call printf there. + This implementation instead uses the <ucontext.h> coroutine + interface. The coroutine stack is still too small to safely use + printf, but we know the OS won't erase it, so we can do all the + checks and printing from the normal stack. */ + +#define _GNU_SOURCE 1 + +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ucontext.h> +#include <unistd.h> + +/* A byte pattern that is unlikely to occur by chance: the first 16 + prime numbers (OEIS A000040). */ +static const unsigned char test_pattern[16] = +{ + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53 +}; + +/* Immediately after each subtest returns, we call swapcontext to get + back onto the main stack. That call might itself overwrite the + test pattern, so we fill a modest-sized buffer with copies of it + and check whether any of them survived. */ + +#define PATTERN_SIZE (sizeof test_pattern) +#define PATTERN_REPS 32 +#define TEST_BUFFER_SIZE (PATTERN_SIZE * PATTERN_REPS) + +/* There are three subtests, two of which are sanity checks. + Each test follows this sequence: + + main coroutine + ---- -------- + advance cur_subtest + swap + call setup function + prepare test buffer + swap + verify that buffer + was filled in + swap + possibly clear buffer + return + swap + check buffer again, + according to test + expectation + + In the "no_clear" case, we don't do anything to the test buffer + between preparing it and letting it go out of scope, and we expect + to find it. This confirms that the test buffer does get filled in + and we can find it from the stack buffer. In the "ordinary_clear" + case, we clear it using memset, and we expect to find it. This + confirms that the compiler can optimize out block clears in this + context; if it can't, the real test might be succeeding for the + wrong reason. Finally, the "explicit_clear" case uses + explicit_bzero and expects _not_ to find the test buffer, which is + the real test. */ + +static ucontext_t uc_main, uc_co; + +/* Always check the test buffer immediately after filling it; this + makes externally visible side effects depend on the buffer existing + and having been filled in. */ +static void +prepare_test_buffer (unsigned char *buf) +{ + for (unsigned int i = 0; i < PATTERN_REPS; i++) + memcpy (buf + i*PATTERN_SIZE, test_pattern, PATTERN_SIZE); + + if (swapcontext (&uc_co, &uc_main)) + abort (); +} + +static void +setup_no_clear (void) +{ + unsigned char buf[TEST_BUFFER_SIZE]; + prepare_test_buffer (buf); +} + +static void +setup_ordinary_clear (void) +{ + unsigned char buf[TEST_BUFFER_SIZE]; + prepare_test_buffer (buf); + memset (buf, 0, TEST_BUFFER_SIZE); +} + +static void +setup_explicit_clear (void) +{ + unsigned char buf[TEST_BUFFER_SIZE]; + prepare_test_buffer (buf); + explicit_bzero (buf, TEST_BUFFER_SIZE); +} + +enum test_expectation { EXPECT_NONE, EXPECT_SOME, EXPECT_ALL }; +struct subtest +{ + void (*setup_subtest) (void); + const char *label; + enum test_expectation expected; +}; +static const struct subtest *cur_subtest; + +static const struct subtest subtests[] = +{ + { setup_no_clear, "no clear", EXPECT_SOME }, + { setup_ordinary_clear, "ordinary clear", EXPECT_SOME }, + { setup_explicit_clear, "explicit clear", EXPECT_NONE }, + { 0, 0, -1 } +}; + +static void +test_coroutine (void) +{ + while (cur_subtest->setup_subtest) + { + cur_subtest->setup_subtest (); + if (swapcontext (&uc_co, &uc_main)) + abort (); + } +} + +/* All the code above this point runs on the coroutine stack. + All the code below this point runs on the main stack. */ + +static int test_status; +static unsigned char *co_stack_buffer; +static size_t co_stack_size; + +static unsigned int +count_test_patterns (unsigned char *buf, size_t bufsiz) +{ + unsigned char *first = memmem (buf, bufsiz, test_pattern, PATTERN_SIZE); + if (!first) + return 0; + unsigned int cnt = 0; + for (unsigned int i = 0; i < PATTERN_REPS; i++) + { + unsigned char *p = first + i*PATTERN_SIZE; + if (p + PATTERN_SIZE - buf > bufsiz) + break; + if (memcmp (p, test_pattern, PATTERN_SIZE) == 0) + cnt++; + } + return cnt; +} + +static void +check_test_buffer (enum test_expectation expected, + const char *label, const char *stage) +{ + unsigned int cnt = count_test_patterns (co_stack_buffer, co_stack_size); + switch (expected) + { + case EXPECT_NONE: + if (cnt == 0) + printf ("PASS: %s/%s: expected 0 got %d\n", label, stage, cnt); + else + { + printf ("FAIL: %s/%s: expected 0 got %d\n", label, stage, cnt); + test_status = 1; + } + break; + + case EXPECT_SOME: + if (cnt > 0) + printf ("PASS: %s/%s: expected some got %d\n", label, stage, cnt); + else + { + printf ("FAIL: %s/%s: expected some got 0\n", label, stage); + test_status = 1; + } + break; + + case EXPECT_ALL: + if (cnt == PATTERN_REPS) + printf ("PASS: %s/%s: expected %d got %d\n", label, stage, + PATTERN_REPS, cnt); + else + { + printf ("FAIL: %s/%s: expected %d got %d\n", label, stage, + PATTERN_REPS, cnt); + test_status = 1; + } + break; + + default: + printf ("ERROR: %s/%s: invalid value for 'expected' = %d\n", + label, stage, (int)expected); + test_status = 1; + } +} + +static void +test_loop (void) +{ + cur_subtest = subtests; + while (cur_subtest->setup_subtest) + { + if (swapcontext (&uc_main, &uc_co)) + abort (); + check_test_buffer (EXPECT_ALL, cur_subtest->label, "prepare"); + if (swapcontext (&uc_main, &uc_co)) + abort (); + check_test_buffer (cur_subtest->expected, cur_subtest->label, "test"); + cur_subtest++; + } + /* Terminate the coroutine. */ + if (swapcontext (&uc_main, &uc_co)) + abort (); +} + +int +do_test (void) +{ + size_t page_alignment = sysconf (_SC_PAGESIZE); + if (page_alignment < sizeof (void *)) + page_alignment = sizeof (void *); + + co_stack_size = SIGSTKSZ + TEST_BUFFER_SIZE; + if (co_stack_size < page_alignment * 4) + co_stack_size = page_alignment * 4; + + void *p; + int err = posix_memalign (&p, page_alignment, co_stack_size); + if (err || !p) + { + printf ("ERROR: allocating alt stack: %s\n", strerror (err)); + return 2; + } + co_stack_buffer = p; + + if (getcontext (&uc_co)) + { + printf ("ERROR: allocating coroutine context: %s\n", strerror (err)); + return 2; + } + uc_co.uc_stack.ss_sp = co_stack_buffer; + uc_co.uc_stack.ss_size = co_stack_size; + uc_co.uc_link = &uc_main; + makecontext (&uc_co, test_coroutine, 0); + + test_loop (); + return test_status; +} + +#include <support/test-driver.c> diff --git a/sysdeps/arm/nacl/libc.abilist b/sysdeps/arm/nacl/libc.abilist index 0a39f4d13e..abd70c8108 100644 --- a/sysdeps/arm/nacl/libc.abilist +++ b/sysdeps/arm/nacl/libc.abilist @@ -1843,6 +1843,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 gnu_dev_major F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 8d3435f210..58d768c6bc 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2090,6 +2090,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 2381616b71..906050d2c3 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2001,6 +2001,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index e2dbf6fee7..66112dd0a7 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -91,6 +91,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 231f039e69..3ddadd2a24 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -1855,6 +1855,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 5d0159348b..977ab90bc7 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2013,6 +2013,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 00ef4d77ab..c7edb9a272 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -1877,6 +1877,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 7de0b0e9bd..450be4e9c1 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -92,6 +92,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 93e1124592..9e016bd76e 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -1969,6 +1969,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index da70083bdd..1a455be0f5 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -2090,6 +2090,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 570bbf6791..8eb5e668b9 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -1944,6 +1944,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 5022e5a186..416d9ac0ae 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -1942,6 +1942,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index ca9f91924f..f4949e5a38 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -1940,6 +1940,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 2a090db5c6..c7375aee3f 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -1935,6 +1935,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index d10bb32513..724a0e3a04 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2131,6 +2131,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index a7e688bed9..2dc32b631c 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -1973,6 +1973,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 8c32c33076..5658109ca2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -1978,6 +1978,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist index 2a13e49a9e..c761221ffe 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist @@ -2178,6 +2178,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index 4f29a6db6e..265c76914b 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist @@ -92,6 +92,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 1e9d4f4d91..ed1b6bf26f 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -1973,6 +1973,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 6b3d9320e1..2e75d29e47 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -1874,6 +1874,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index 93b79d3758..bd74c0cdab 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -1859,6 +1859,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index a29b0c149b..5584838409 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -1965,6 +1965,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 8ac06e9b01..efedbe2874 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -1903,6 +1903,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist index 208e7425ff..ffd988a33d 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist index 3d7836d546..f0c13ceea8 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist index 208e7425ff..ffd988a33d 100644 --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 32cd1e07b4..f57004c860 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -1854,6 +1854,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 4ff7acf300..05629e17e7 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F GLIBC_2.24 GLIBC_2.24 A GLIBC_2.24 quick_exit F GLIBC_2.25 GLIBC_2.25 A +GLIBC_2.25 __explicit_bzero_chk F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 getentropy F GLIBC_2.25 getrandom F GLIBC_2.25 strfromd F |