Message ID | 9d17da53214c24a908092519d98bb93f4e6429f1.1471452664.git.zackw@panix.com |
---|---|
State | New |
Headers | show |
On 08/17/2016 07:19 PM, Zack Weinberg wrote: > +#ifdef __USE_MISC > +/* As bzero, but the compiler will not delete a call to this > + function, even if S is dead after the call. Note: this function > + has its own implementation file and should not be slurped into > + string-inlines.o. */ > +__extern_inline void > +explicit_bzero (void *__s, size_t __n) > +{ > + memset (__s, '\0', __n); > + __glibc_read_memory (__s, __n); > +} > +#endif __extern_inline can expand to nothing at all, and you would get multiple definitions of explicit_bzero this way. I don't think we want explicit_bzero to be inlined, it's useful to have this name in the executable. Furthermore, we might want to add additional state clearing later, so an implementation in libc.so.6 seems desirable anyway. For an implementation in libc, there is currently no different between the __glibc_read_memory kludge and a full memory barrier, so I suggest to go with the latter. (The explicit_bzero call will serve as a rather broad barrier anyway, but we can annotate it with __THROW.) Thanks, Florian
On Thu, 2016-08-18 at 20:31 +0200, Florian Weimer wrote: > On 08/17/2016 07:19 PM, Zack Weinberg wrote: > > +#ifdef __USE_MISC > > +/* As bzero, but the compiler will not delete a call to this > > + function, even if S is dead after the call. Note: this function > > + has its own implementation file and should not be slurped into > > + string-inlines.o. */ > > +__extern_inline void > > +explicit_bzero (void *__s, size_t __n) > > +{ > > + memset (__s, '\0', __n); > > + __glibc_read_memory (__s, __n); > > +} > > +#endif > > __extern_inline can expand to nothing at all, and you would get multiple > definitions of explicit_bzero this way. > > I don't think we want explicit_bzero to be inlined, it's useful to have > this name in the executable. Furthermore, we might want to add > additional state clearing later, so an implementation in libc.so.6 seems > desirable anyway. > > For an implementation in libc, there is currently no different between > the __glibc_read_memory kludge and a full memory barrier, so I suggest > to go with the latter. (The explicit_bzero call will serve as a rather > broad barrier anyway, but we can annotate it with __THROW.) I suppose we just want a compiler barrier here though, and don't need a memory barrier in the sense of something that constrains HW reordering.
On 18/08/2016 17:53, Torvald Riegel wrote: > On Thu, 2016-08-18 at 20:31 +0200, Florian Weimer wrote: >> On 08/17/2016 07:19 PM, Zack Weinberg wrote: >>> +#ifdef __USE_MISC >>> +/* As bzero, but the compiler will not delete a call to this >>> + function, even if S is dead after the call. Note: this function >>> + has its own implementation file and should not be slurped into >>> + string-inlines.o. */ >>> +__extern_inline void >>> +explicit_bzero (void *__s, size_t __n) >>> +{ >>> + memset (__s, '\0', __n); >>> + __glibc_read_memory (__s, __n); >>> +} >>> +#endif >> >> __extern_inline can expand to nothing at all, and you would get multiple >> definitions of explicit_bzero this way. >> >> I don't think we want explicit_bzero to be inlined, it's useful to have >> this name in the executable. Furthermore, we might want to add >> additional state clearing later, so an implementation in libc.so.6 seems >> desirable anyway. >> >> For an implementation in libc, there is currently no different between >> the __glibc_read_memory kludge and a full memory barrier, so I suggest >> to go with the latter. (The explicit_bzero call will serve as a rather >> broad barrier anyway, but we can annotate it with __THROW.) > > I suppose we just want a compiler barrier here though, and don't need a > memory barrier in the sense of something that constrains HW reordering. I would also suggest to avoid adding this inline optimization, it just add another exported symbol by glibc with little performance benefit.
On 08/18/2016 10:53 PM, Torvald Riegel wrote: > On Thu, 2016-08-18 at 20:31 +0200, Florian Weimer wrote: >> I don't think we want explicit_bzero to be inlined, it's useful to have >> this name in the executable. Furthermore, we might want to add >> additional state clearing later, so an implementation in libc.so.6 seems >> desirable anyway. >> >> For an implementation in libc, there is currently no different between >> the __glibc_read_memory kludge and a full memory barrier, so I suggest >> to go with the latter. (The explicit_bzero call will serve as a rather >> broad barrier anyway, but we can annotate it with __THROW.) > > I suppose we just want a compiler barrier here though, and don't need a > memory barrier in the sense of something that constrains HW reordering. Yes, I meant an asm statement with a "memory" clobber. Thanks, Florian
On 08/19/2016 08:43 AM, Adhemerval Zanella wrote: > On 18/08/2016 17:53, Torvald Riegel wrote: >> On Thu, 2016-08-18 at 20:31 +0200, Florian Weimer wrote: >>> On 08/17/2016 07:19 PM, Zack Weinberg wrote: >>>> +#ifdef __USE_MISC >>>> +/* As bzero, but the compiler will not delete a call to this >>>> + function, even if S is dead after the call. Note: this function >>>> + has its own implementation file and should not be slurped into >>>> + string-inlines.o. */ >>>> +__extern_inline void >>>> +explicit_bzero (void *__s, size_t __n) >>>> +{ >>>> + memset (__s, '\0', __n); >>>> + __glibc_read_memory (__s, __n); >>>> +} >>>> +#endif >>> >>> __extern_inline can expand to nothing at all, and you would get multiple >>> definitions of explicit_bzero this way. OK, what should I be using instead? >>> I don't think we want explicit_bzero to be inlined, it's useful to have >>> this name in the executable. Furthermore, we might want to add >>> additional state clearing later, so an implementation in libc.so.6 seems >>> desirable anyway. Oddly enough, inlining the memset leads to better security properties for generated code. Remember the "key that lives in the vector registers until it has to be copied onto the stack to be erased" scenario? --- #include <emmintrin.h> #include <string.h> extern void explicit_bzero (void *ptr, size_t size); extern __m128 get_key (); extern void encrypt_with_key (__m128 key, void *data, size_t size); void encrypt (void *data, size_t size) { __m128 key = get_key (); encrypt_with_key (key, data, size); explicit_bzero (&key, sizeof key); } --- (Assume an ABI where __m128 actually gets passed in registers.) If you expose the memset to inlining, the key *won't* be copied into the stack and then immediately erased; the compiler will just dutifully clear 16 bytes of the stack and then pass them to __glibc_read_memory. It still won't be erased from the vector registers, but that can only be fixed with compiler support. (It also leads to significantly more compact code -- see my experiment with OpenSSL from last year -- but that's not as important.) >> I suppose we just want a compiler barrier here though, and don't need a >> memory barrier in the sense of something that constrains HW reordering. That is correct; however, the "memory barrier" I was talking about was asm volatile ("" ::: "memory"); which is also only a compiler barrier. > I would also suggest to avoid adding this inline optimization, it just add > another exported symbol by glibc with little performance benefit. The *other* reason why I want to keep the inline optimization is that it means I don't need to add __explicit_bzero_chk (which, because of ifuncs, means futzing with *every sysdeps definition of memset*!). So either way there's going to be a new exported symbol. zw
On 19/08/2016 10:00, Zack Weinberg wrote: > On 08/19/2016 08:43 AM, Adhemerval Zanella wrote: >> On 18/08/2016 17:53, Torvald Riegel wrote: >>> On Thu, 2016-08-18 at 20:31 +0200, Florian Weimer wrote: >>>> On 08/17/2016 07:19 PM, Zack Weinberg wrote: >>>>> +#ifdef __USE_MISC >>>>> +/* As bzero, but the compiler will not delete a call to this >>>>> + function, even if S is dead after the call. Note: this function >>>>> + has its own implementation file and should not be slurped into >>>>> + string-inlines.o. */ >>>>> +__extern_inline void >>>>> +explicit_bzero (void *__s, size_t __n) >>>>> +{ >>>>> + memset (__s, '\0', __n); >>>>> + __glibc_read_memory (__s, __n); >>>>> +} >>>>> +#endif >>>> >>>> __extern_inline can expand to nothing at all, and you would get multiple >>>> definitions of explicit_bzero this way. > > OK, what should I be using instead? Fortify functions uses '__fortify_function' which defines both __extern_always_inline and __attribute_artificial__. However fortify is guarded by _FORTIFY_SOURCE, which requires GCC 4.1 (so __extern_always_inline will be defined anyway). Stdio also defines: #ifndef __extern_inline # define __STDIO_INLINE inline #else # define __STDIO_INLINE __extern_inline #endif #ifdef __USE_EXTERN_INLINES ... #endif But I think this will also only add unnecessary complexity on the patch. Also, another issue with gnu_inline is when building for C++ it might get also multiple definitions [1]. That's why I think simpler solution would be just to remove this inline optimization. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41194 > >>>> I don't think we want explicit_bzero to be inlined, it's useful to have >>>> this name in the executable. Furthermore, we might want to add >>>> additional state clearing later, so an implementation in libc.so.6 seems >>>> desirable anyway. > > Oddly enough, inlining the memset leads to better security properties > for generated code. Remember the "key that lives in the vector > registers until it has to be copied onto the stack to be erased" scenario? > > --- > #include <emmintrin.h> > #include <string.h> > > extern void explicit_bzero (void *ptr, size_t size); > > extern __m128 get_key (); > extern void encrypt_with_key (__m128 key, void *data, size_t size); > > void encrypt (void *data, size_t size) > { > __m128 key = get_key (); > encrypt_with_key (key, data, size); > explicit_bzero (&key, sizeof key); > } > --- > > (Assume an ABI where __m128 actually gets passed in registers.) > > If you expose the memset to inlining, the key *won't* be copied into > the stack and then immediately erased; the compiler will just dutifully > clear 16 bytes of the stack and then pass them to __glibc_read_memory. > It still won't be erased from the vector registers, but that can only be > fixed with compiler support. > > (It also leads to significantly more compact code -- see my experiment > with OpenSSL from last year -- but that's not as important.) I also think compact code should not be a blocker here as well. However I do not have a better solution for this specific solution without compiler support. > >>> I suppose we just want a compiler barrier here though, and don't need a >>> memory barrier in the sense of something that constrains HW reordering. > > That is correct; however, the "memory barrier" I was talking about was > > asm volatile ("" ::: "memory"); > > which is also only a compiler barrier. > >> I would also suggest to avoid adding this inline optimization, it just add >> another exported symbol by glibc with little performance benefit. > > The *other* reason why I want to keep the inline optimization is that it > means I don't need to add __explicit_bzero_chk (which, because of > ifuncs, means futzing with *every sysdeps definition of memset*!). So > either way there's going to be a new exported symbol. > > zw I do not think this is really required, you can still add a default debug/explicit_bzero_chk.c which will call explicit_bzero/memset. Each port already defines how internal memset is called (either using internal ifunc or redirecting to a default symbol) so I see no need to add arch specific implementations. This does not prevent though to later we add arch-specific optimized version (which might be ifunc).
On Fri, Aug 19, 2016 at 10:00 AM, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > On 19/08/2016 10:00, Zack Weinberg wrote: >> >> OK, what should I be using instead? > > [... some options which I will look into ...] > > That's why I think simpler solution would be just to remove this inline > optimization. It's really, really not simpler, though, because of the fortify issue... >> The *other* reason why I want to keep the inline optimization is that it >> means I don't need to add __explicit_bzero_chk (which, because of >> ifuncs, means futzing with *every sysdeps definition of memset*!). So >> either way there's going to be a new exported symbol. > > I do not think this is really required, you can still add a default > debug/explicit_bzero_chk.c which will call explicit_bzero/memset. You missed the point; the point was that if we don't add __glibc_read_memory then we have to add __explicit_bzero_chk, so there's one new implementation-namespace exported symbol either way. Anyway, it would be nice if that worked without modifying every definition of memset, but it doesn't. The problem is not that __explicit_bzero_chk itself would need to be an ifunc (I agree that that would be an unnecessary optimization); the problem is that __explicit_bzero_chk would need to call __memset_chk from inside libc.so. There are currently no calls to __memset_chk inside libc.so, which means there is no PLT bypass glue for __memset_chk. And because _some_ architectures define __memset_chk as an ifunc, it's in sysdeps, and _every_ memset.S has to be audited and possibly touched. This is such a PITA that in https://sourceware.org/ml/libc-alpha/2015-11/msg00467.html I appear to have only done it for x86. With the inline optimization, the fortified explicit_bzero can live entirely within bits/string3.h and no modifications to __memset_chk are required. zw
On 19/08/2016 13:06, Zack Weinberg wrote: > On Fri, Aug 19, 2016 at 10:00 AM, Adhemerval Zanella > <adhemerval.zanella@linaro.org> wrote: >> On 19/08/2016 10:00, Zack Weinberg wrote: >>> >>> OK, what should I be using instead? >> >> [... some options which I will look into ...] >> >> That's why I think simpler solution would be just to remove this inline >> optimization. > > It's really, really not simpler, though, because of the fortify issue... > >>> The *other* reason why I want to keep the inline optimization is that it >>> means I don't need to add __explicit_bzero_chk (which, because of >>> ifuncs, means futzing with *every sysdeps definition of memset*!). So >>> either way there's going to be a new exported symbol. >> >> I do not think this is really required, you can still add a default >> debug/explicit_bzero_chk.c which will call explicit_bzero/memset. > > You missed the point; the point was that if we don't add > __glibc_read_memory then we have to add __explicit_bzero_chk, so > there's one new implementation-namespace exported symbol either way. > > Anyway, it would be nice if that worked without modifying every > definition of memset, but it doesn't. The problem is not that > __explicit_bzero_chk itself would need to be an ifunc (I agree that > that would be an unnecessary optimization); the problem is that > __explicit_bzero_chk would need to call __memset_chk from inside > libc.so. There are currently no calls to __memset_chk inside libc.so, > which means there is no PLT bypass glue for __memset_chk. And because > _some_ architectures define __memset_chk as an ifunc, it's in sysdeps, > and _every_ memset.S has to be audited and possibly touched. This is > such a PITA that in > https://sourceware.org/ml/libc-alpha/2015-11/msg00467.html I appear to > have only done it for x86. > > With the inline optimization, the fortified explicit_bzero can live > entirely within bits/string3.h and no modifications to __memset_chk > are required. Well, current memset_chk default implementation just does: if (__glibc_unlikely (dstlen < len)) __chk_fail (); So it would be feasible imho to just this add and call memset instead of memset_chk. The problem, as pointed out by Florian, is not the symbol being exported itself, but the inline definition where all the 'inline' definition might either not being supported by the target compiler or have non-expected side effects (as for C++ with -O0). The fortified version is mostly fine to use 'inline' definition because it is already guarded by _FORTIFY_SOURCE, but I think the default explicit_bzero guarded by __USE_MISC is not suffice.
On Fri, Aug 19, 2016 at 12:31 PM, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > Well, current memset_chk default implementation just does: > > if (__glibc_unlikely (dstlen < len)) > __chk_fail (); > > So it would be feasible imho to just this add and call memset instead > of memset_chk. For clarity, you are imagining this as the in-libc, out-of-line implementation of __explicit_bzero_chk? Because as long as there's *some* inline definition of explicit_bzero, we have to have the exported __glibc_read_memory and then I don't see why we shouldn't have a string2.h non-fortified inline as well. > The problem, as pointed out by Florian, is not the symbol being exported > itself, but the inline definition where all the 'inline' definition might > either not being supported by the target compiler or have non-expected > side effects (as for C++ with -O0). Did you miss that there *is* an out-of-line non-fortified explicit_bzero? Which means that the bug you pointed out should be a non-issue. zw
On 19/08/2016 16:54, Zack Weinberg wrote: > On Fri, Aug 19, 2016 at 12:31 PM, Adhemerval Zanella > <adhemerval.zanella@linaro.org> wrote: >> Well, current memset_chk default implementation just does: >> >> if (__glibc_unlikely (dstlen < len)) >> __chk_fail (); >> >> So it would be feasible imho to just this add and call memset instead >> of memset_chk. > > For clarity, you are imagining this as the in-libc, out-of-line > implementation of __explicit_bzero_chk? Because as long as there's > *some* inline definition of explicit_bzero, we have to have the > exported __glibc_read_memory and then I don't see why we shouldn't > have a string2.h non-fortified inline as well. What I would like is, based on recent string inline headers cleanup, is to avoid adding more implementation that in the future the compiler can and would handle this transparently. Ideally it would be better if we just aims to clean all the optimization done in string2/string3 headers (as we did for recent strspn, strbrk, etc. optimizations). For this special case, I would advise go for the simple case: add a explicit_bzero and __explicit_bzero_chk in-libc as the other implementations. However I do not have a strong opinion here. > >> The problem, as pointed out by Florian, is not the symbol being exported >> itself, but the inline definition where all the 'inline' definition might >> either not being supported by the target compiler or have non-expected >> side effects (as for C++ with -O0). > > Did you miss that there *is* an out-of-line non-fortified > explicit_bzero? Which means that the bug you pointed out should be a > non-issue. The problem is not the existence of a out-of-line explicit_bzero, but if __extern_inline would use or not the gnu_inline attribute. With current guards for inclusion of string2.h (OPTIMIZE and !__cplusplus) the only case of a possible issue I can think of is if someone building with GCC lower than 4.2 with an optimized build and -fno-inline (this will define __extern_inline to just extern __inline and possible create multiple definitions). My inclination is this should not be a blocker though.
diff --git a/include/string.h b/include/string.h index e145bfd..277c07d 100644 --- a/include/string.h +++ b/include/string.h @@ -99,6 +99,8 @@ libc_hidden_proto (memmem) extern __typeof (memmem) __memmem; libc_hidden_proto (__memmem) libc_hidden_proto (__ffs) +extern __typeof (__glibc_read_memory) __internal_glibc_read_memory; +libc_hidden_proto (__internal_glibc_read_memory) libc_hidden_builtin_proto (memchr) libc_hidden_builtin_proto (memcpy) diff --git a/manual/string.texi b/manual/string.texi index bce81a7..fe4ca48 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. @@ -2375,6 +2377,105 @@ 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 + +It is sometimes necessary to make sure that a block of data in memory +is erased after use, even if no correct C program could access it +again. For instance, a cryptographic key should not be allowed to +survive on the stack after the program is finished using it, because +there might be a bug that causes junk stack data, including the key, +to be revealed to the outside world. @code{memset} and @code{bzero} +are not safe to use for this, because the C compiler knows what they +do, and can delete ``unnecessary'' calls to them. For this situation, +@theglibc{} provides @code{explicit_bzero}, which is functionally +identical to @code{bzero}, except that the C compiler will @emph{not} +delete apparently-unnecessary calls. + +@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 each of the first @var{len} +bytes of the object beginning at @var{block}, just as @code{bzero} +would. The compiler will not delete a call to this function, even +if the object beginning at @var{block} is never referred to again. + +@smallexample +#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 smallexample + +@noindent +If @code{bzero} or @code{memset} had been used in this function, the C +compiler might remove it as unnecessary, but it will not do this with +@code{explicit_bzero}. + +@strong{Warning:} The @emph{only} optimization disabled by +@code{explicit_bzero} is removal of ``unnecessary'' calls. In all +other respects, the compiler is allowed to optimize as it would for +@code{memset}. For instance, it may deduce that @var{block} cannot be +a null pointer, and propagate this information both forward and +backward in control flow. + +@strong{Warning:} The compiler is free to make additional copies of +any object, or parts of it, in temporary storage areas (such as +registers and ``scratch'' stack space). @code{explicit_bzero} does +not guarantee that temporary copies of sensitive data are destroyed. +In fact, in some situations, using @code{explicit_bzero} will +@emph{cause} creation of an additional copy, and only that copy will +be cleared: + +@smallexample +#include <string.h> + +struct key @{ + unsigned long long low; + unsigned long long high; +@}; + +struct key get_key(void); +void use_key(struct key); + +void +with_clear(void) +@{ + struct key k; + k = get_key(); + use_key(k); + explicit_bzero(&k, sizeof(k)); +@} +@end smallexample + +@noindent +Without the call to @code{explicit_bzero}, @var{k} might not need to +be stored in memory: depending on the ABI, its value could be returned +from @code{get_key} and passed to @code{use_key} using only CPU +registers. @code{explicit_bzero} operates on memory, so the compiler +has to make a copy of @var{k} in memory for it, and the copy in the +CPU registers remains intact. This can occur for any variable whose +address is only taken in a call to @code{explicit_bzero}, even if it +might seem ``too large'' to be stored in registers. + +@strong{Portability Note:} This function first appeared in OpenBSD 5.5 +and has not been standardized. @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 9c87419..180ec86 100644 --- a/string/Makefile +++ b/string/Makefile @@ -41,13 +41,19 @@ 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 + +# Attention future hackers trying to enable link-time optimization for +# glibc: this file *must not* be subject to LTO. It is added separately +# to 'routines' to document this. See comments in this file for details. +routines += read_memory 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 \ diff --git a/string/Versions b/string/Versions index 475c1fd..b5c24f4 100644 --- a/string/Versions +++ b/string/Versions @@ -82,4 +82,11 @@ libc { } GLIBC_2.24 { } + GLIBC_2.25 { + # used by inlines in string2.h + __glibc_read_memory; + + # e* + explicit_bzero; + } } diff --git a/string/bits/string2.h b/string/bits/string2.h index 8098760..f890585 100644 --- a/string/bits/string2.h +++ b/string/bits/string2.h @@ -52,11 +52,23 @@ #define __string2_1bptr_p(__x) \ ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1) -/* Set N bytes of S to C. */ +/* Set N bytes of S to 0. */ #if !defined _HAVE_STRING_ARCH_memset # define __bzero(s, n) __builtin_memset (s, '\0', n) #endif +#ifdef __USE_MISC +/* As bzero, but the compiler will not delete a call to this + function, even if S is dead after the call. Note: this function + has its own implementation file and should not be slurped into + string-inlines.o. */ +__extern_inline void +explicit_bzero (void *__s, size_t __n) +{ + memset (__s, '\0', __n); + __glibc_read_memory (__s, __n); +} +#endif #ifndef _HAVE_STRING_ARCH_strchr extern void *__rawmemchr (const void *__s, int __c); diff --git a/string/explicit_bzero.c b/string/explicit_bzero.c new file mode 100644 index 0000000..a02be4f --- /dev/null +++ b/string/explicit_bzero.c @@ -0,0 +1,30 @@ +/* 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/>. */ + +#include <features.h> +#undef __USE_STRING_INLINES +#define __NO_STRING_INLINES +#include <string.h> + +/* 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); + __internal_glibc_read_memory (s, len); +} diff --git a/string/read_memory.c b/string/read_memory.c new file mode 100644 index 0000000..c4a5990 --- /dev/null +++ b/string/read_memory.c @@ -0,0 +1,41 @@ +/* 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/>. */ + +#include <string.h> + +/* This function is an optimization fence. It doesn't do anything + itself, but calls to it prevent calls to explicit_bzero from being + optimized away. In order to achieve this effect, this function + must never, under any circumstances, be inlined or subjected to + inter-procedural optimization. string.h declares this function + with attributes that, in conjunction with the no-op asm insert, are + sufficient to prevent problems in the current (2016) generation of + compilers, but *only if* this file is *not* compiled with -flto. + At present, this is not an issue since glibc is never compiled with + -flto, but should that ever change, this file must be excepted. + + The 'volatile' below is technically not necessary but is included + for explicitness. */ + +void +internal_function +__internal_glibc_read_memory(const void *s, size_t len) +{ + asm volatile (""); +} +libc_hidden_def (__internal_glibc_read_memory) +strong_alias (__internal_glibc_read_memory, __glibc_read_memory) diff --git a/string/string.h b/string/string.h index 57deaa4..40851b5 100644 --- a/string/string.h +++ b/string/string.h @@ -455,6 +455,15 @@ 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)); + +/* Optimization fence, used by bits/string2.h inline version of + explicit_bzero. */ +extern void __glibc_read_memory (const void *__s, size_t __n) + __THROW __nonnull ((1)) __attribute_noinline__; + /* 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 0000000..5a4543b --- /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 fee3bdf..7ca4f20 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/sysdeps/arm/nacl/libc.abilist b/sysdeps/arm/nacl/libc.abilist index 4d3b0b9..02d4bc6 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.25 gnu_dev_major F GLIBC_2.25 gnu_dev_makedev F GLIBC_2.25 gnu_dev_minor F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 2c2f49e..44dc0d1 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2090,3 +2090,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 8afba47..02a490d 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index de3bdf4..d2b2800 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 3261b93..59b2591 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 6465a55..e64f9c6 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 4536271..78acf45 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 287d7a5..ceb1909 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index c9229fa..e8d7256 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index 0409791..c2e2ecc 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -2090,3 +2090,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index f31653e..705f00b 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index a56bd99..41d3e5c 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 44552df..4de5839 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 8d2a09d..e1d5bec 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 0443b92..34e83a6 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2131,3 +2131,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index ba9a29a..91a30c8 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index f19534c..a4ecbc2 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist index f8de1ab..277ec26 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist @@ -2178,3 +2178,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index 6819133..e3dafa5 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 _Exit F GLIBC_2.3 _IO_2_1_stderr_ D 0xe0 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 4cd5d85..3ab826d 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 8cdb9df..c4c0a8e 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index 69791b4..7a11b8a 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index fce58a8..13efb9f 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 16ce739..da6819b 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist index f99c298..0d58dc0 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist @@ -2097,3 +2097,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist index c601ab0..fc55930 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist @@ -2097,3 +2097,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist index f99c298..0d58dc0 100644 --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist @@ -2097,3 +2097,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 8e6fa57..858a26c 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 1e12f48..9a45eed 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2097,3 +2097,5 @@ 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 __glibc_read_memory F +GLIBC_2.25 explicit_bzero F