From: Christian Göttsche Date: Mon, 3 Jan 2022 14:03:34 +0000 (+0100) Subject: Ensure memory cleaning X-Git-Tag: 4.12~95^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a799ebb2c304010c1aad16490e7354c7e7659a2;p=thirdparty%2Fshadow.git 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 --- diff --git a/configure.ac b/configure.ac index 5dcae191a..6fc29292a 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 fc1521cbe..3aeaa0029 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 */