diff --git a/include/wx/utils.h b/include/wx/utils.h index ac5f6241d3..274f2a1aaa 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -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 // ---------------------------------------------------------------------------- diff --git a/interface/wx/utils.h b/interface/wx/utils.h index 4e83ce490f..2731b414fe 100644 --- a/interface/wx/utils.h +++ b/interface/wx/utils.h @@ -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, diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index 8f5402f6e2..3505230de3 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -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(v); + while ( n-- ) + *p++ = c; +#else + RtlSecureZeroMemory(v, n); +#endif +} + // ---------------------------------------------------------------------------- // process management // ---------------------------------------------------------------------------- diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index 36906c84c7..63786c60b0 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -113,6 +113,8 @@ #define _LANGUAGE_C_PLUS_PLUS 1 #endif // SGI hack +#define __STDC_WANT_LIB_EXT1__ 1 // for memset_s() in + #include #include #include @@ -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(v); + while ( n-- ) + *p++ = c; +#endif +} + // ---------------------------------------------------------------------------- // process management // ----------------------------------------------------------------------------