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