Index: lib/libc/string/bzero.3 =================================================================== --- lib/libc/string/bzero.3 +++ lib/libc/string/bzero.3 @@ -62,9 +62,9 @@ .Pp The .Fn explicit_bzero -variant behaves the same, but will not be removed by a compiler's dead store -optimization pass, making it useful for clearing sensitive memory such as a -password. +variant is the same, but has correct flags to force the call to occur, +no matter if the compiler thinks it is pointless, or not, making it +useful for clearing sensitive memory such as a password. .Sh SEE ALSO .Xr memset 3 , .Xr swab 3 Index: sys/libkern/explicit_bzero.c =================================================================== --- sys/libkern/explicit_bzero.c +++ sys/libkern/explicit_bzero.c @@ -2,6 +2,8 @@ /* * Public domain. * Written by Matthew Dempsky. + * + * reworked by Jim Thompson */ #include @@ -13,6 +15,40 @@ #include #endif /* _KERNEL */ +#if __clang__ + /* + * http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros + * http://lists.cs.uiuc.edu/pipermail/cfe-dev/2014-December/040627.html + */ + #if __has_attribute( noinline ) /* && __has_attribute( optnone ) */ + #define NOOPT /* __attribute__ (( optnone )) */ + #define NOINLINE __attribute__ (( noinline )) + #endif +#elif __GNUC__ + /* + * http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html + * http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + */ + #if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 ) + #define NOOPT __attribute__ (( optimize( 0 ) )) + #define NOINLINE __attribute__ (( noinline )) + #endif +#endif + +#if defined(NOOPT) && defined(NOINLINE) +NOOPT NOINLINE void +explicit_bzero(void *buf, size_t len) +{ + size_t i; + unsigned char *p = buf; + + for (i = 0; i < len; i++) { + p[i] = 0; + } +} + +#else + __attribute__((weak)) void __explicit_bzero_hook(void *, size_t); __attribute__((weak)) void @@ -26,3 +62,4 @@ memset(buf, 0, len); __explicit_bzero_hook(buf, len); } +#endif