1 /* Erase sensitive data from memory. 2 Copyright 2022-2023 Free Software Foundation, Inc. 3 4 This file is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 2.1 of the 7 License, or (at your option) any later version. 8 9 This file is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16 17 #include <config.h> 18 19 /* memset_s need this define */ 20 #if HAVE_MEMSET_S 21 # define __STDC_WANT_LIB_EXT1__ 1 22 #endif 23 24 #include <string.h> 25 26 /* Set S's bytes to C, where S has LEN bytes. The compiler will not 27 optimize effects away, even if S is dead after the call. */ 28 void * 29 memset_explicit (void *s, int c, size_t len) 30 { 31 #if HAVE_EXPLICIT_MEMSET 32 return explicit_memset (s, c, len); 33 #elif HAVE_MEMSET_S 34 (void) memset_s (s, len, c, len); 35 return s; 36 #elif defined __GNUC__ && !defined __clang__ 37 memset (s, c, len); 38 /* Compiler barrier. */ 39 __asm__ volatile ("" ::: "memory"); 40 return s; 41 #elif defined __clang__ 42 memset (s, c, len); 43 /* Compiler barrier. */ 44 /* With asm ("" ::: "memory") LLVM analyzes uses of 's' and finds that the 45 whole thing is dead and eliminates it. Use 'g' to work around this 46 problem. See <https://bugs.llvm.org/show_bug.cgi?id=15495#c11>. */ 47 __asm__ volatile ("" : : "g"(s) : "memory"); 48 return s; 49 #else 50 /* Invoke memset through a volatile function pointer. This defeats compiler 51 optimizations. */ 52 void * (* const volatile volatile_memset) (void *, int, size_t) = memset; 53 return volatile_memset (s, c, len); 54 #endif 55 }