xref: /freebsd-src/contrib/libfido2/openbsd-compat/explicit_bzero.c (revision 0afa8e065e14bb8fd338d75690e0238c00167d40)
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