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