From 21fdef6963539680a16b68b7536378bdaa8dea85 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 1 Dec 2018 13:43:09 +0200 Subject: [PATCH] common: Use platform memory zeroing function for wipememory * common/mischelp.h (wipememory): Replace macro with function prototype. (wipememory2): Remove. * common/mischelp.c (wipememory): New. * configure.ac (AC_CHECK_FUNCS): Check for 'explicit_bzero' and remove duplicated checks. -- In new wipememory function, memory is cleared through platform provided secure memory zeroing function, SecureZeroMemory or explicit_bzero. If none of these is available, memset is called through volatile function pointer to so that compiler won't optimize away the call. Signed-off-by: Jussi Kivilinna (cherry picked from commit 2a650772b4e1c78a4fd20bc88433930e5551fe9c) --- common/mischelp.c | 16 ++++++++++++++++ common/mischelp.h | 12 +++--------- configure.ac | 23 +++++++++++------------ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/common/mischelp.c b/common/mischelp.c index 75ba60714..81dd501f8 100644 --- a/common/mischelp.c +++ b/common/mischelp.c @@ -49,6 +49,22 @@ #include "mischelp.h" +void +wipememory (void *ptr, size_t len) +{ +#if defined(HAVE_W32_SYSTEM) && defined(SecureZeroMemory) + SecureZeroMemory (ptr, len); +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero (ptr, len); +#else + /* Prevent compiler from optimizing away the call to memset by accessing + memset through volatile pointer. */ + static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset; + memset_ptr (ptr, 0, len); +#endif +} + + /* Check whether the files NAME1 and NAME2 are identical. This is for example achieved by comparing the inode numbers of the files. */ int diff --git a/common/mischelp.h b/common/mischelp.h index 18ec96edf..bdee5a443 100644 --- a/common/mischelp.h +++ b/common/mischelp.h @@ -47,15 +47,9 @@ time_t timegm (struct tm *tm); #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) -/* To avoid that a compiler optimizes certain memset calls away, these - macros may be used instead. */ -#define wipememory2(_ptr,_set,_len) do { \ - volatile char *_vptr=(volatile char *)(_ptr); \ - size_t _vlen=(_len); \ - while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ - } while(0) -#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) - +/* To avoid that a compiler optimizes certain memset calls away, + wipememory function may be used instead. */ +void wipememory(void *ptr, size_t len); /* Include hacks which are mainly required for Slowaris. */ #ifdef GNUPG_COMMON_NEED_AFLOCAL diff --git a/configure.ac b/configure.ac index 4d21545a3..2c0bc80da 100644 --- a/configure.ac +++ b/configure.ac @@ -1382,18 +1382,17 @@ AC_CHECK_DECLS(getpagesize) AC_FUNC_FSEEKO AC_FUNC_VPRINTF AC_FUNC_FORK -AC_CHECK_FUNCS([strerror strlwr tcgetattr mmap canonicalize_file_name]) -AC_CHECK_FUNCS([strcasecmp strncasecmp ctermid times gmtime_r strtoull]) -AC_CHECK_FUNCS([setenv unsetenv fcntl ftruncate inet_ntop]) -AC_CHECK_FUNCS([canonicalize_file_name]) -AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime]) -AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale]) -AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe getaddrinfo]) -AC_CHECK_FUNCS([ttyname rand ftello fsync stat lstat]) -AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \ - memrchr isascii timegm getrusage setrlimit stat setlocale \ - flockfile funlockfile getpwnam getpwuid \ - getenv inet_pton strpbrk]) +AC_CHECK_FUNCS([atexit canonicalize_file_name clock_gettime ctermid \ + explicit_bzero fcntl flockfile fsync ftello \ + ftruncate funlockfile getaddrinfo getenv getpagesize \ + getpwnam getpwuid getrlimit getrusage gettimeofday \ + gmtime_r inet_ntop inet_pton isascii lstat memicmp \ + memmove memrchr mmap nl_langinfo pipe raise rand \ + setenv setlocale setrlimit sigaction sigprocmask \ + stat stpcpy strcasecmp strerror strftime stricmp \ + strlwr strncasecmp strpbrk strsep strtol strtoul \ + strtoull tcgetattr timegm times ttyname unsetenv \ + wait4 waitpid ]) # On some systems (e.g. Solaris) nanosleep requires linking to librl. # Given that we use nanosleep only as an optimization over a select