1263635Sdes/* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */
2263635Sdes/*	$OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */
3263635Sdes/*
4263635Sdes * Public domain.
5263635Sdes * Written by Ted Unangst
6263635Sdes */
7263635Sdes
8263635Sdes#include "includes.h"
9263635Sdes
10323134Sdes#include <string.h>
11323134Sdes
12294328Sdes/*
13294328Sdes * explicit_bzero - don't let the compiler optimize away bzero
14294328Sdes */
15294328Sdes
16263635Sdes#ifndef HAVE_EXPLICIT_BZERO
17263635Sdes
18294328Sdes#ifdef HAVE_MEMSET_S
19294328Sdes
20294328Sdesvoid
21294328Sdesexplicit_bzero(void *p, size_t n)
22294328Sdes{
23294328Sdes	(void)memset_s(p, n, 0, n);
24294328Sdes}
25294328Sdes
26294328Sdes#else /* HAVE_MEMSET_S */
27294328Sdes
28263635Sdes/*
29294328Sdes * Indirect bzero through a volatile pointer to hopefully avoid
30294328Sdes * dead-store optimisation eliminating the call.
31263635Sdes */
32294328Sdesstatic void (* volatile ssh_bzero)(void *, size_t) = bzero;
33294328Sdes
34263635Sdesvoid
35263635Sdesexplicit_bzero(void *p, size_t n)
36263635Sdes{
37323134Sdes	/*
38323134Sdes	 * clang -fsanitize=memory needs to intercept memset-like functions
39323134Sdes	 * to correctly detect memory initialisation. Make sure one is called
40323134Sdes	 * directly since our indirection trick above sucessfully confuses it.
41323134Sdes	 */
42323134Sdes#if defined(__has_feature)
43323134Sdes# if __has_feature(memory_sanitizer)
44323134Sdes	memset(p, 0, n);
45323134Sdes# endif
46323134Sdes#endif
47323134Sdes
48294328Sdes	ssh_bzero(p, n);
49263635Sdes}
50294328Sdes
51294328Sdes#endif /* HAVE_MEMSET_S */
52294328Sdes
53294328Sdes#endif /* HAVE_EXPLICIT_BZERO */
54