1 #ifndef __STDC_WANT_LIB_EXT1__
2 #define __STDC_WANT_LIB_EXT1__ 1
3 #endif
4
5 #include "ruby/missing.h"
6 #include <string.h>
7 #ifdef HAVE_MEMSET_S
8 # include <string.h>
9 #endif
10
11 #ifdef _WIN32
12 #include <windows.h>
13 #endif
14
15 /* Similar to bzero(), but has a guarantee not to be eliminated from compiler
16 optimization. */
17
18 /* OS support note:
19 * BSDs have explicit_bzero().
20 * OS-X has memset_s().
21 * Windows has SecureZeroMemory() since XP.
22 * Linux has none. *Sigh*
23 */
24
25 /*
26 * Following URL explains why memset_s is added to the standard.
27 * http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf
28 */
29
30 #ifndef FUNC_UNOPTIMIZED
31 # define FUNC_UNOPTIMIZED(x) x
32 #endif
33
34 #undef explicit_bzero
35 #ifndef HAVE_EXPLICIT_BZERO
36 #ifdef HAVE_MEMSET_S
37 void
explicit_bzero(void * b,size_t len)38 explicit_bzero(void *b, size_t len)
39 {
40 memset_s(b, len, 0, len);
41 }
42 #elif defined SecureZeroMemory
43 void
explicit_bzero(void * b,size_t len)44 explicit_bzero(void *b, size_t len)
45 {
46 SecureZeroMemory(b, len);
47 }
48
49 #elif defined HAVE_FUNC_WEAK
50
51 /* A weak function never be optimized away. Even if nobody uses it. */
52 WEAK(void ruby_explicit_bzero_hook_unused(void *buf, size_t len));
53 void
ruby_explicit_bzero_hook_unused(void * buf,size_t len)54 ruby_explicit_bzero_hook_unused(void *buf, size_t len)
55 {
56 }
57
58 void
explicit_bzero(void * b,size_t len)59 explicit_bzero(void *b, size_t len)
60 {
61 memset(b, 0, len);
62 ruby_explicit_bzero_hook_unused(b, len);
63 }
64
65 #else /* Your OS have no capability. Sigh. */
66
67 FUNC_UNOPTIMIZED(void explicit_bzero(void *b, size_t len));
68 #undef explicit_bzero
69
70 void
explicit_bzero(void * b,size_t len)71 explicit_bzero(void *b, size_t len)
72 {
73 /*
74 * volatile is not enough if the compiler has an LTO (link time
75 * optimization). At least, the standard provides no guarantee.
76 * However, gcc and major other compilers never optimize a volatile
77 * variable away. So, using volatile is practically ok.
78 */
79 volatile char* p = (volatile char*)b;
80
81 while(len) {
82 *p = 0;
83 p++;
84 len--;
85 }
86 }
87 #endif
88 #endif /* HAVE_EXPLICIT_BZERO */
89