From 7a799ebb2c304010c1aad16490e7354c7e7659a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Mon, 3 Jan 2022 15:03:34 +0100 Subject: [PATCH] Ensure memory cleaning Compilers are allowed to and do optimize memset(3) calls away for pointers not accessed in the future. Since the memzero wrappers purpose is exactly to unconditionally override memory (e.g. for stored passwords) do not implement via regular memset(3), but via either memset_s(3), explicit_bzero(3) or a hand written implementation using volatile pointers. See https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations --- configure.ac | 2 +- lib/defines.h | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 5dcae191..6fc29292 100644 --- a/configure.ac +++ b/configure.ac @@ -56,7 +56,7 @@ AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes \ getutent initgroups lchown lckpwdf lstat lutimes \ setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \ getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \ - dlopen) + dlopen memset_s explicit_bzero) AC_SYS_LARGEFILE dnl Checks for typedefs, structures, and compiler characteristics. diff --git a/lib/defines.h b/lib/defines.h index fc1521cb..3aeaa002 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -111,7 +111,20 @@ char *strchr (), *strrchr (), *strtok (); # endif #endif /* not TIME_WITH_SYS_TIME */ -#define memzero(ptr, size) memset((void *)(ptr), 0, (size)) +#ifdef HAVE_MEMSET_S +# define memzero(ptr, size) memset_s((ptr), 0, (size)) +#elif defined HAVE_EXPLICIT_BZERO /* !HAVE_MEMSET_S */ +# define memzero(ptr, size) explicit_bzero((ptr), (size)) +#else /* !HAVE_MEMSET_S && HAVE_EXPLICIT_BZERO */ +static inline void memzero(void *ptr, size_t size) +{ + volatile unsigned char * volatile p = ptr; + while (size--) { + *p++ = '\0'; + } +} +#endif /* !HAVE_MEMSET_S && !HAVE_EXPLICIT_BZERO */ + #define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */ #ifdef HAVE_DIRENT_H /* DIR_SYSV */