1 /* Erasure of sensitive data, generic implementation. 2 Copyright (C) 2016-2023 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 /* An assembler implementation of explicit_bzero can be created as an 20 assembler alias of an optimized bzero implementation. 21 Architecture-specific implementations also need to define 22 __explicit_bzero_chk. */ 23 24 #if !_LIBC 25 # include <config.h> 26 #endif 27 28 /* memset_s need this define */ 29 #if HAVE_MEMSET_S 30 # define __STDC_WANT_LIB_EXT1__ 1 31 #endif 32 33 #include <string.h> 34 35 #if defined _WIN32 && !defined __CYGWIN__ 36 # define WIN32_LEAN_AND_MEAN 37 # include <windows.h> 38 #endif 39 40 #if _LIBC 41 /* glibc-internal users use __explicit_bzero_chk, and explicit_bzero 42 redirects to that. */ 43 # undef explicit_bzero 44 #endif 45 46 /* Set LEN bytes of S to 0. The compiler will not delete a call to 47 this function, even if S is dead after the call. */ 48 void 49 explicit_bzero (void *s, size_t len) 50 { 51 #if defined _WIN32 && !defined __CYGWIN__ 52 (void) SecureZeroMemory (s, len); 53 #elif HAVE_EXPLICIT_MEMSET 54 explicit_memset (s, '\0', len); 55 #elif HAVE_MEMSET_S 56 (void) memset_s (s, len, '\0', len); 57 #elif defined __GNUC__ && !defined __clang__ 58 memset (s, '\0', len); 59 /* Compiler barrier. */ 60 asm volatile ("" ::: "memory"); 61 #elif defined __clang__ 62 memset (s, '\0', len); 63 /* Compiler barrier. */ 64 /* With asm ("" ::: "memory") LLVM analyzes uses of 's' and finds that the 65 whole thing is dead and eliminates it. Use 'g' to work around this 66 problem. See <https://bugs.llvm.org/show_bug.cgi?id=15495#c11>. */ 67 __asm__ volatile ("" : : "g"(s) : "memory"); 68 #else 69 /* Invoke memset through a volatile function pointer. This defeats compiler 70 optimizations. */ 71 void * (* const volatile volatile_memset) (void *, int, size_t) = memset; 72 (void) volatile_memset (s, '\0', len); 73 #endif 74 }