Ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a25176072e02db9254f0e0c84c805cd)
explicit_bzero.c
Go to the documentation of this file.
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_EXPLICIT_MEMSET
37void
38explicit_bzero(void *b, size_t len)
39{
40 (void)explicit_memset(b, 0, len);
41}
42 #elif defined HAVE_MEMSET_S
43void
44explicit_bzero(void *b, size_t len)
45{
46 memset_s(b, len, 0, len);
47}
48 #elif defined SecureZeroMemory
49void
50explicit_bzero(void *b, size_t len)
51{
52 SecureZeroMemory(b, len);
53}
54
55 #elif defined HAVE_FUNC_WEAK
56
57/* A weak function never be optimized away. Even if nobody uses it. */
58WEAK(void ruby_explicit_bzero_hook_unused(void *buf, size_t len));
59void
60ruby_explicit_bzero_hook_unused(void *buf, size_t len)
61{
62}
63
64void
65explicit_bzero(void *b, size_t len)
66{
67 memset(b, 0, len);
68 ruby_explicit_bzero_hook_unused(b, len);
69}
70
71 #else /* Your OS have no capability. Sigh. */
72
73FUNC_UNOPTIMIZED(void explicit_bzero(void *b, size_t len));
74#undef explicit_bzero
75
76void
77explicit_bzero(void *b, size_t len)
78{
79 /*
80 * volatile is not enough if the compiler has an LTO (link time
81 * optimization). At least, the standard provides no guarantee.
82 * However, gcc and major other compilers never optimize a volatile
83 * variable away. So, using volatile is practically ok.
84 */
85 volatile char* p = (volatile char*)b;
86
87 while(len) {
88 *p = 0;
89 p++;
90 len--;
91 }
92}
93 #endif
94#endif /* HAVE_EXPLICIT_BZERO */
void explicit_bzero(void *b, size_t len)
#define FUNC_UNOPTIMIZED(x)
__inline__ const void *__restrict__ size_t len
#define WEAK(x)
void * memset(void *, int, size_t)
struct rb_call_cache buf