mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 02:03:35 +08:00
ea1bd74def
explicit_bzero(s, n) is the same as memset(s, 0, n), except that the compiler is not allowed to delete a call to explicit_bzero even if the memory pointed to by 's' is dead after the call. Right now, this effect is achieved externally by having explicit_bzero be a function whose semantics are unknown to the compiler, and internally, with a no-op asm statement that clobbers memory. This does mean that small explicit_bzero operations cannot be expanded inline as small memset operations can, but on the other hand, small memset operations do get deleted by the compiler. Hopefully full compiler support for explicit_bzero will happen relatively soon. There are two new tests: test-explicit_bzero.c verifies the visible semantics in the same way as the existing test-bzero.c, and tst-xbzero-opt.c verifies the not-being-optimized-out property. The latter is conceptually based on a test written by Matthew Dempsky for the OpenBSD regression suite. The crypt() implementation has an immediate use for this new feature. We avoid having to add a GLIBC_PRIVATE alias for explicit_bzero by running all of libcrypt's calls through the fortified variant, __explicit_bzero_chk, which is in the impl namespace anyway. Currently I'm not aware of anything in libc proper that needs this, but the glue is all in place if it does become necessary. The legacy DES implementation wasn't bothering to clear its buffers, so I added that, mostly for consistency's sake. * 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.
200 lines
6.6 KiB
C
200 lines
6.6 KiB
C
#ifndef _STRING_H
|
|
|
|
#ifndef _ISOMAC
|
|
#include <sys/types.h>
|
|
|
|
extern void *__memccpy (void *__dest, const void *__src,
|
|
int __c, size_t __n);
|
|
|
|
extern size_t __strnlen (const char *__string, size_t __maxlen)
|
|
__attribute_pure__;
|
|
|
|
extern char *__strsep (char **__stringp, const char *__delim);
|
|
|
|
extern int __strverscmp (const char *__s1, const char *__s2)
|
|
__attribute_pure__;
|
|
|
|
extern int __strncasecmp (const char *__s1, const char *__s2,
|
|
size_t __n)
|
|
__attribute_pure__;
|
|
|
|
extern int __strcasecmp (const char *__s1, const char *__s2)
|
|
__attribute_pure__;
|
|
|
|
extern char *__strcasestr (const char *__haystack, const char *__needle)
|
|
__attribute_pure__;
|
|
|
|
extern char *__strdup (const char *__string)
|
|
__attribute_malloc__;
|
|
extern char *__strndup (const char *__string, size_t __n)
|
|
__attribute_malloc__;
|
|
|
|
extern void *__rawmemchr (const void *__s, int __c)
|
|
__attribute_pure__;
|
|
|
|
extern char *__strchrnul (const char *__s, int __c)
|
|
__attribute_pure__;
|
|
|
|
extern void *__memrchr (const void *__s, int __c, size_t __n)
|
|
__attribute_pure__;
|
|
|
|
extern void *__memchr (const void *__s, int __c, size_t __n)
|
|
__attribute_pure__;
|
|
|
|
extern int __ffs (int __i) __attribute__ ((const));
|
|
|
|
extern char *__strerror_r (int __errnum, char *__buf, size_t __buflen);
|
|
#endif
|
|
|
|
/* Get _STRING_ARCH_unaligned. */
|
|
#include <string_private.h>
|
|
|
|
/* Now the real definitions. We do this here since some of the functions
|
|
above are defined as macros in the headers. */
|
|
#include <string/string.h>
|
|
|
|
#ifndef _ISOMAC
|
|
extern __typeof (strcoll_l) __strcoll_l;
|
|
extern __typeof (strxfrm_l) __strxfrm_l;
|
|
extern __typeof (strcasecmp_l) __strcasecmp_l;
|
|
extern __typeof (strncasecmp_l) __strncasecmp_l;
|
|
|
|
/* Alternative version which doesn't pollute glibc's namespace. */
|
|
#if IS_IN (libc)
|
|
# undef strndupa
|
|
# define strndupa(s, n) \
|
|
(__extension__ \
|
|
({ \
|
|
const char *__old = (s); \
|
|
size_t __len = __strnlen (__old, (n)); \
|
|
char *__new = (char *) __builtin_alloca (__len + 1); \
|
|
__new[__len] = '\0'; \
|
|
(char *) memcpy (__new, __old, __len); \
|
|
}))
|
|
#endif
|
|
|
|
libc_hidden_proto (__mempcpy)
|
|
libc_hidden_proto (__stpcpy)
|
|
libc_hidden_proto (__stpncpy)
|
|
libc_hidden_proto (__rawmemchr)
|
|
libc_hidden_proto (__strcasecmp)
|
|
libc_hidden_proto (__strcasecmp_l)
|
|
libc_hidden_proto (__strncasecmp_l)
|
|
libc_hidden_proto (__strdup)
|
|
libc_hidden_proto (__strndup)
|
|
libc_hidden_proto (__strerror_r)
|
|
libc_hidden_proto (__strverscmp)
|
|
libc_hidden_proto (basename)
|
|
extern char *__basename (const char *__filename) __THROW __nonnull ((1));
|
|
libc_hidden_proto (__basename)
|
|
libc_hidden_proto (strcoll)
|
|
libc_hidden_proto (__strcoll_l)
|
|
libc_hidden_proto (__strxfrm_l)
|
|
libc_hidden_proto (__strtok_r)
|
|
extern char *__strsep_g (char **__stringp, const char *__delim);
|
|
libc_hidden_proto (__strsep_g)
|
|
libc_hidden_proto (strnlen)
|
|
libc_hidden_proto (__strnlen)
|
|
libc_hidden_proto (memmem)
|
|
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)
|
|
libc_hidden_builtin_proto (memcmp)
|
|
libc_hidden_builtin_proto (memmove)
|
|
libc_hidden_builtin_proto (memset)
|
|
libc_hidden_builtin_proto (strcat)
|
|
libc_hidden_builtin_proto (strchr)
|
|
libc_hidden_builtin_proto (strcmp)
|
|
libc_hidden_builtin_proto (strcpy)
|
|
libc_hidden_builtin_proto (strcspn)
|
|
libc_hidden_builtin_proto (strlen)
|
|
libc_hidden_builtin_proto (strncmp)
|
|
libc_hidden_builtin_proto (strncpy)
|
|
libc_hidden_builtin_proto (strpbrk)
|
|
libc_hidden_builtin_proto (stpcpy)
|
|
libc_hidden_builtin_proto (strrchr)
|
|
libc_hidden_builtin_proto (strspn)
|
|
libc_hidden_builtin_proto (strstr)
|
|
libc_hidden_builtin_proto (ffs)
|
|
|
|
#if IS_IN (rtld)
|
|
extern __typeof (__stpcpy) __stpcpy attribute_hidden;
|
|
extern __typeof (__strdup) __strdup attribute_hidden;
|
|
extern __typeof (__strerror_r) __strerror_r attribute_hidden;
|
|
extern __typeof (__strsep_g) __strsep_g attribute_hidden;
|
|
|
|
extern __typeof (memchr) memchr attribute_hidden;
|
|
extern __typeof (memcmp) memcmp attribute_hidden;
|
|
extern __typeof (memcpy) memcpy attribute_hidden;
|
|
extern __typeof (memmove) memmove attribute_hidden;
|
|
extern __typeof (memset) memset attribute_hidden;
|
|
extern __typeof (rawmemchr) rawmemchr attribute_hidden;
|
|
extern __typeof (stpcpy) stpcpy attribute_hidden;
|
|
extern __typeof (strchr) strchr attribute_hidden;
|
|
extern __typeof (strcmp) strcmp attribute_hidden;
|
|
extern __typeof (strlen) strlen attribute_hidden;
|
|
extern __typeof (strnlen) strnlen attribute_hidden;
|
|
extern __typeof (strsep) strsep attribute_hidden;
|
|
#endif
|
|
|
|
#if (!IS_IN (libc) || !defined SHARED) \
|
|
&& !defined NO_MEMPCPY_STPCPY_REDIRECT
|
|
/* Redirect calls to __builtin_mempcpy and __builtin_stpcpy to call
|
|
__mempcpy and __stpcpy if not inlined. */
|
|
extern __typeof (mempcpy) mempcpy __asm__ ("__mempcpy");
|
|
extern __typeof (stpcpy) stpcpy __asm__ ("__stpcpy");
|
|
#endif
|
|
|
|
# ifndef _ISOMAC
|
|
# ifndef index
|
|
# define index(s, c) (strchr ((s), (c)))
|
|
# endif
|
|
# ifndef rindex
|
|
# define rindex(s, c) (strrchr ((s), (c)))
|
|
# endif
|
|
# endif
|
|
|
|
extern void *__memcpy_chk (void *__restrict __dest,
|
|
const void *__restrict __src, size_t __len,
|
|
size_t __destlen) __THROW;
|
|
extern void *__memmove_chk (void *__dest, const void *__src, size_t __len,
|
|
size_t __destlen) __THROW;
|
|
extern void *__mempcpy_chk (void *__restrict __dest,
|
|
const void *__restrict __src, size_t __len,
|
|
size_t __destlen) __THROW;
|
|
extern void *__memset_chk (void *__dest, int __ch, size_t __len,
|
|
size_t __destlen) __THROW;
|
|
extern char *__strcpy_chk (char *__restrict __dest,
|
|
const char *__restrict __src,
|
|
size_t __destlen) __THROW;
|
|
extern char *__stpcpy_chk (char *__restrict __dest,
|
|
const char *__restrict __src,
|
|
size_t __destlen) __THROW;
|
|
extern char *__strncpy_chk (char *__restrict __dest,
|
|
const char *__restrict __src,
|
|
size_t __len, size_t __destlen) __THROW;
|
|
extern char *__strcat_chk (char *__restrict __dest,
|
|
const char *__restrict __src,
|
|
size_t __destlen) __THROW;
|
|
extern char *__strncat_chk (char *__restrict __dest,
|
|
const char *__restrict __src,
|
|
size_t __len, size_t __destlen) __THROW;
|
|
#endif
|
|
|
|
#endif
|