Implement wxSecureZeroMemory() for clearing memory securely

Wrap native function when possible, and fallback to a generic
implementation.

Closes https://github.com/wxWidgets/wxWidgets/pull/2582
This commit is contained in:
Lauri Nurmi
2021-11-05 18:28:07 +02:00
committed by Vadim Zeitlin
parent 4f7e09374a
commit 90c20798b9
4 changed files with 70 additions and 0 deletions

View File

@@ -324,6 +324,12 @@ WXDLLIMPEXP_BASE void wxDecToHex(unsigned char dec, wxChar *buf);
WXDLLIMPEXP_BASE void wxDecToHex(unsigned char dec, char* ch1, char* ch2);
WXDLLIMPEXP_BASE wxString wxDecToHex(unsigned char dec);
// ----------------------------------------------------------------------------
// Security
// ----------------------------------------------------------------------------
WXDLLIMPEXP_BASE void wxSecureZeroMemory(void *p, size_t n);
// ----------------------------------------------------------------------------
// Process management
// ----------------------------------------------------------------------------

View File

@@ -335,6 +335,23 @@ bool wxGetEnvMap(wxEnvVariableHashMap *map);
/** @addtogroup group_funcmacro_misc */
//@{
/**
Fills the memory block with zeros in a way that is guaranteed
not to be optimized away by the compiler.
@param p Pointer to the memory block to be zeroed, must be non-@NULL.
@param n The number of bytes to zero.
NOTE: If security is vitally important in your use case, please
have a look at the implementations and decide whether you trust
them to behave as promised.
@header{wx/utils.h}
@since 3.1.6
*/
void wxSecureZeroMemory(void *p, size_t n);
/**
Returns battery state as one of @c wxBATTERY_NORMAL_STATE,
@c wxBATTERY_LOW_STATE, @c wxBATTERY_CRITICAL_STATE,

View File

@@ -550,6 +550,24 @@ bool wxUnsetEnv(const wxString& variable)
return wxDoSetEnv(variable, NULL);
}
// ----------------------------------------------------------------------------
// security
// ----------------------------------------------------------------------------
void wxSecureZeroMemory(void* v, size_t n)
{
#if defined(__MINGW32__)
// A generic implementation based on the example at:
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf
int c = 0;
volatile unsigned char *p = reinterpret_cast<unsigned char *>(v);
while ( n-- )
*p++ = c;
#else
RtlSecureZeroMemory(v, n);
#endif
}
// ----------------------------------------------------------------------------
// process management
// ----------------------------------------------------------------------------

View File

@@ -113,6 +113,8 @@
#define _LANGUAGE_C_PLUS_PLUS 1
#endif // SGI hack
#define __STDC_WANT_LIB_EXT1__ 1 // for memset_s() in <string.h>
#include <stdarg.h>
#include <dirent.h>
#include <string.h>
@@ -202,6 +204,33 @@ void wxMilliSleep(unsigned long milliseconds)
wxMicroSleep(milliseconds*1000);
}
// ----------------------------------------------------------------------------
// security
// ----------------------------------------------------------------------------
void wxSecureZeroMemory(void* v, size_t n)
{
#if (defined(__GLIBC__) && \
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) || \
(defined(__FreeBSD__) && __FreeBSD__ >= 11)
// This non-standard function is somewhat widely available elsewhere too,
// but may be found in a non-standard header file, or in a library that is
// not linked by default.
explicit_bzero(v, n);
#elif defined(__DARWIN__) || defined(__STDC_LIB_EXT1__)
// memset_s() is available since OS X 10.9, and may be available on
// other platforms.
memset_s(v, n, 0, n);
#else
// A generic implementation based on the example at:
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf
int c = 0;
volatile unsigned char *p = reinterpret_cast<unsigned char *>(v);
while ( n-- )
*p++ = c;
#endif
}
// ----------------------------------------------------------------------------
// process management
// ----------------------------------------------------------------------------