Ruby: missing/explicit_bzero.c Source File

Ruby 3.4.7p58 (2025-10-08 revision 7a5688e2a27668e48f8d6ff4af5b2208b98a2f5e)

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