aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2017-07-16 16:22:33 -0700
committerPaul Eggert2017-07-16 16:29:12 -0700
commit59f6972134f312863dc761bf66a954a8036d0d86 (patch)
treecd479a7fe59b72985f98e57c4b4d861c01cf5bc8
parent252444aaa3a7cb9fc70289a5a3920f8a9d848109 (diff)
downloademacs-59f6972134f312863dc761bf66a954a8036d0d86.tar.gz
emacs-59f6972134f312863dc761bf66a954a8036d0d86.zip
Use explicit_bzero to clear GnuTLS keys
* admin/merge-gnulib (GNULIB_MODULES): Add explicit_bzero. * lib/explicit_bzero.c, m4/explicit_bzero.m4: New files. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * src/gnutls.c (clear_storage): New function. (gnutls_symmetric_aead): Use it instead of memset.
-rwxr-xr-xadmin/merge-gnulib2
-rw-r--r--lib/explicit_bzero.c48
-rw-r--r--lib/gnulib.mk.in13
-rw-r--r--m4/explicit_bzero.m422
-rw-r--r--m4/gnulib-comp.m49
-rw-r--r--src/gnutls.c20
6 files changed, 110 insertions, 4 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 85921ba1ba6..2b1a16a10ec 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -30,7 +30,7 @@ GNULIB_MODULES='
30 careadlinkat close-stream 30 careadlinkat close-stream
31 count-leading-zeros count-one-bits count-trailing-zeros 31 count-leading-zeros count-one-bits count-trailing-zeros
32 crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 32 crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512
33 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat 33 diffseq dtoastr dtotimespec dup2 environ execinfo explicit_bzero faccessat
34 fcntl fcntl-h fdatasync fdopendir 34 fcntl fcntl-h fdatasync fdopendir
35 filemode filevercmp flexmember fstatat fsync 35 filemode filevercmp flexmember fstatat fsync
36 getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog 36 getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
diff --git a/lib/explicit_bzero.c b/lib/explicit_bzero.c
new file mode 100644
index 00000000000..262c68f9cd6
--- /dev/null
+++ b/lib/explicit_bzero.c
@@ -0,0 +1,48 @@
1/* Erasure of sensitive data, generic implementation.
2 Copyright (C) 2016-2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19/* An assembler implementation of explicit_bzero can be created as an
20 assembler alias of an optimized bzero implementation.
21 Architecture-specific implementations also need to define
22 __explicit_bzero_chk. */
23
24#if !_LIBC
25# include <config.h>
26#endif
27
28#include <string.h>
29
30/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero
31 redirects to that. */
32#undef explicit_bzero
33
34/* Set LEN bytes of S to 0. The compiler will not delete a call to
35 this function, even if S is dead after the call. */
36void
37explicit_bzero (void *s, size_t len)
38{
39#ifdef HAVE_EXPLICIT_MEMSET
40 explicit_memset (s, 0, len);
41#else
42 memset (s, '\0', len);
43# ifdef __GNUC__
44 /* Compiler barrier. */
45 asm volatile ("" ::: "memory");
46# endif
47#endif
48}
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index ae5ae87a521..e20487b10b4 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -21,7 +21,7 @@
21# the same distribution terms as the rest of that program. 21# the same distribution terms as the rest of that program.
22# 22#
23# Generated by gnulib-tool. 23# Generated by gnulib-tool.
24# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unlocked-io update-copyright utimens vla warnings 24# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo explicit_bzero faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unlocked-io update-copyright utimens vla warnings
25 25
26 26
27MOSTLYCLEANFILES += core *.stackdump 27MOSTLYCLEANFILES += core *.stackdump
@@ -1358,6 +1358,17 @@ EXTRA_libgnu_a_SOURCES += execinfo.c
1358endif 1358endif
1359## end gnulib module execinfo 1359## end gnulib module execinfo
1360 1360
1361## begin gnulib module explicit_bzero
1362ifeq (,$(OMIT_GNULIB_MODULE_explicit_bzero))
1363
1364
1365EXTRA_DIST += explicit_bzero.c
1366
1367EXTRA_libgnu_a_SOURCES += explicit_bzero.c
1368
1369endif
1370## end gnulib module explicit_bzero
1371
1361## begin gnulib module faccessat 1372## begin gnulib module faccessat
1362ifeq (,$(OMIT_GNULIB_MODULE_faccessat)) 1373ifeq (,$(OMIT_GNULIB_MODULE_faccessat))
1363 1374
diff --git a/m4/explicit_bzero.m4 b/m4/explicit_bzero.m4
new file mode 100644
index 00000000000..f9dc678207a
--- /dev/null
+++ b/m4/explicit_bzero.m4
@@ -0,0 +1,22 @@
1dnl Copyright 2017 Free Software Foundation, Inc.
2dnl This file is free software; the Free Software Foundation
3dnl gives unlimited permission to copy and/or distribute it,
4dnl with or without modifications, as long as this notice is preserved.
5
6AC_DEFUN([gl_FUNC_EXPLICIT_BZERO],
7[
8 AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
9
10 dnl Persuade glibc <string.h> to declare explicit_bzero.
11 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
12
13 AC_CHECK_FUNCS_ONCE([explicit_bzero])
14 if test $ac_cv_func_explicit_bzero = no; then
15 HAVE_EXPLICIT_BZERO=0
16 fi
17])
18
19AC_DEFUN([gl_PREREQ_EXPLICIT_BZERO],
20[
21 AC_CHECK_FUNCS([explicit_memset])
22])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 107645df4fd..038d78aafea 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -72,6 +72,7 @@ AC_DEFUN([gl_EARLY],
72 # Code from module errno: 72 # Code from module errno:
73 # Code from module euidaccess: 73 # Code from module euidaccess:
74 # Code from module execinfo: 74 # Code from module execinfo:
75 # Code from module explicit_bzero:
75 # Code from module extensions: 76 # Code from module extensions:
76 # Code from module extern-inline: 77 # Code from module extern-inline:
77 # Code from module faccessat: 78 # Code from module faccessat:
@@ -210,6 +211,12 @@ AC_DEFUN([gl_INIT],
210 gl_UNISTD_MODULE_INDICATOR([environ]) 211 gl_UNISTD_MODULE_INDICATOR([environ])
211 gl_HEADER_ERRNO_H 212 gl_HEADER_ERRNO_H
212 gl_EXECINFO_H 213 gl_EXECINFO_H
214 gl_FUNC_EXPLICIT_BZERO
215 if test $HAVE_EXPLICIT_BZERO = 0; then
216 AC_LIBOBJ([explicit_bzero])
217 gl_PREREQ_EXPLICIT_BZERO
218 fi
219 gl_STRING_MODULE_INDICATOR([explicit_bzero])
213 AC_REQUIRE([gl_EXTERN_INLINE]) 220 AC_REQUIRE([gl_EXTERN_INLINE])
214 gl_FUNC_FACCESSAT 221 gl_FUNC_FACCESSAT
215 if test $HAVE_FACCESSAT = 0; then 222 if test $HAVE_FACCESSAT = 0; then
@@ -837,6 +844,7 @@ AC_DEFUN([gl_FILE_LIST], [
837 lib/euidaccess.c 844 lib/euidaccess.c
838 lib/execinfo.c 845 lib/execinfo.c
839 lib/execinfo.in.h 846 lib/execinfo.in.h
847 lib/explicit_bzero.c
840 lib/faccessat.c 848 lib/faccessat.c
841 lib/fcntl.c 849 lib/fcntl.c
842 lib/fcntl.in.h 850 lib/fcntl.in.h
@@ -967,6 +975,7 @@ AC_DEFUN([gl_FILE_LIST], [
967 m4/errno_h.m4 975 m4/errno_h.m4
968 m4/euidaccess.m4 976 m4/euidaccess.m4
969 m4/execinfo.m4 977 m4/execinfo.m4
978 m4/explicit_bzero.m4
970 m4/extensions.m4 979 m4/extensions.m4
971 m4/extern-inline.m4 980 m4/extern-inline.m4
972 m4/faccessat.m4 981 m4/faccessat.m4
diff --git a/src/gnutls.c b/src/gnutls.c
index e6f01a9cfe1..7d19f90fbb8 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -1883,6 +1883,22 @@ The alist key is the cipher name. */)
1883 return ciphers; 1883 return ciphers;
1884} 1884}
1885 1885
1886/* Zero out STORAGE (even if it will become inaccessible. It has
1887 STORAGE_LENGTH bytes. The goal is to improve security a bit, in
1888 case an Emacs module or some buggy part of Emacs attempts to
1889 inspect STORAGE later to retrieve a secret.
1890
1891 Calls to this function document when storage containing a secret is
1892 known to go out of scope. This function is not guaranteed to erase
1893 the secret, as copies of STORAGE may well be accessible elsewhere
1894 on the machine. */
1895
1896static void
1897clear_storage (void *storage, ptrdiff_t storage_length)
1898{
1899 explicit_bzero (storage, storage_length);
1900}
1901
1886static Lisp_Object 1902static Lisp_Object
1887gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, 1903gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca,
1888 Lisp_Object cipher, 1904 Lisp_Object cipher,
@@ -1949,7 +1965,7 @@ gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca,
1949 1965
1950 if (ret < GNUTLS_E_SUCCESS) 1966 if (ret < GNUTLS_E_SUCCESS)
1951 { 1967 {
1952 memset (storage, 0, storage_length); 1968 clear_storage (storage, storage_length);
1953 SAFE_FREE (); 1969 SAFE_FREE ();
1954 gnutls_aead_cipher_deinit (acipher); 1970 gnutls_aead_cipher_deinit (acipher);
1955 if (encrypting) 1971 if (encrypting)
@@ -1963,7 +1979,7 @@ gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca,
1963 gnutls_aead_cipher_deinit (acipher); 1979 gnutls_aead_cipher_deinit (acipher);
1964 1980
1965 Lisp_Object output = make_unibyte_string (storage, storage_length); 1981 Lisp_Object output = make_unibyte_string (storage, storage_length);
1966 memset (storage, 0, storage_length); 1982 clear_storage (storage, storage_length);
1967 SAFE_FREE (); 1983 SAFE_FREE ();
1968 return list2 (output, actual_iv); 1984 return list2 (output, actual_iv);
1969#else 1985#else