1*46988a0eSchristos /* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */
2*46988a0eSchristos /* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */
3*46988a0eSchristos /*
4*46988a0eSchristos * Public domain.
5*46988a0eSchristos * Written by Ted Unangst
6*46988a0eSchristos */
7*46988a0eSchristos
8*46988a0eSchristos #include <string.h>
9*46988a0eSchristos
10*46988a0eSchristos /*
11*46988a0eSchristos * explicit_bzero - don't let the compiler optimize away bzero
12*46988a0eSchristos */
13*46988a0eSchristos
14*46988a0eSchristos #ifndef HAVE_EXPLICIT_BZERO
15*46988a0eSchristos
16*46988a0eSchristos #include "util.h"
17*46988a0eSchristos
18*46988a0eSchristos #ifdef HAVE_MEMSET_S
19*46988a0eSchristos
explicit_bzero(void * p,size_t n)20*46988a0eSchristos void explicit_bzero(void *p, size_t n) {
21*46988a0eSchristos if (n == 0)
22*46988a0eSchristos return;
23*46988a0eSchristos (void) memset_s(p, n, 0, n);
24*46988a0eSchristos }
25*46988a0eSchristos
26*46988a0eSchristos #else /* HAVE_MEMSET_S */
27*46988a0eSchristos
28*46988a0eSchristos /*
29*46988a0eSchristos * Indirect bzero through a volatile pointer to hopefully avoid
30*46988a0eSchristos * dead-store optimisation eliminating the call.
31*46988a0eSchristos */
32*46988a0eSchristos static void (*volatile ssh_bzero)(void *, size_t) = bzero;
33*46988a0eSchristos
explicit_bzero(void * p,size_t n)34*46988a0eSchristos void explicit_bzero(void *p, size_t n) {
35*46988a0eSchristos if (n == 0)
36*46988a0eSchristos return;
37*46988a0eSchristos /*
38*46988a0eSchristos * clang -fsanitize=memory needs to intercept memset-like functions
39*46988a0eSchristos * to correctly detect memory initialisation. Make sure one is called
40*46988a0eSchristos * directly since our indirection trick above successfully confuses it.
41*46988a0eSchristos */
42*46988a0eSchristos #if defined(__has_feature)
43*46988a0eSchristos #if __has_feature(memory_sanitizer)
44*46988a0eSchristos memset(p, 0, n);
45*46988a0eSchristos #endif
46*46988a0eSchristos #endif
47*46988a0eSchristos
48*46988a0eSchristos ssh_bzero(p, n);
49*46988a0eSchristos }
50*46988a0eSchristos
51*46988a0eSchristos #endif /* HAVE_MEMSET_S */
52*46988a0eSchristos
53*46988a0eSchristos #endif /* HAVE_EXPLICIT_BZERO */
54