aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog59
-rw-r--r--NEWS6
-rw-r--r--crypt/crypt-entry.c9
-rw-r--r--crypt/md5-crypt.c8
-rw-r--r--crypt/sha256-crypt.c14
-rw-r--r--crypt/sha512-crypt.c14
-rw-r--r--debug/Makefile1
-rw-r--r--debug/Versions3
-rw-r--r--debug/explicit_bzero_chk.c44
-rw-r--r--debug/tst-chk1.c28
-rw-r--r--include/string.h11
-rw-r--r--manual/string.texi99
-rw-r--r--string/Makefile7
-rw-r--r--string/Versions3
-rw-r--r--string/bits/string3.h9
-rw-r--r--string/explicit_bzero.c38
-rw-r--r--string/string.h4
-rw-r--r--string/test-explicit_bzero.c20
-rw-r--r--string/test-memset.c10
-rw-r--r--string/tst-xbzero-opt.c288
-rw-r--r--sysdeps/arm/nacl/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/arm/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/i386/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sh/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist2
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))
+