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
This commit is contained in:
Christian Göttsche 2022-01-03 15:03:34 +01:00
parent eccf1c569c
commit 7a799ebb2c
2 changed files with 15 additions and 2 deletions

View File

@ -56,7 +56,7 @@ AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes \
getutent initgroups lchown lckpwdf lstat lutimes \ getutent initgroups lchown lckpwdf lstat lutimes \
setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \ setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \
getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \ getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \
dlopen) dlopen memset_s explicit_bzero)
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.

View File

@ -111,7 +111,20 @@ char *strchr (), *strrchr (), *strtok ();
# endif # endif
#endif /* not TIME_WITH_SYS_TIME */ #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 */ #define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */
#ifdef HAVE_DIRENT_H /* DIR_SYSV */ #ifdef HAVE_DIRENT_H /* DIR_SYSV */