There is an issue where calls to bzero (memset(), etc) can be eliminated due to an optimizing compiler eliminating the call to bzero() (or memset(), etc) because the arguments to the call are not subsequently used by the function. The compiler can interpret this as "no side effects", and eliminate the call.
The origin source of issue to being brought to light with a 'security focus' is here: http://cwe.mitre.org/data/definitions/14.html
OpenBSD implemented explicit_bzero() as a response (over a decade after the report) in OpenBSD 5.5 (released May 1, 2014).
The implementation in OpenBSD is here:
FreeBSD subsequently copied this implementation.
I believe both implementations are flawed.
Link Time Optimization (LTO) is a problem for several implementations of explicit_bzero(). LTO enabled today with clang, it also works with several versions of GCC, and only the absence of WITH_LLD_IS_LLD=yes in src.conf is keeping LTO from being enabled in the linker with:
CFLAGS = -O <any level) -flto
LDFLAGS += -fuse-ld=lld
This style of implementation in FreeBSD (and by extension OpenBSD) today is flawed, because the compiler/linker is free to look into the
call tree and still eliminate the call. The issue shows up on LTO (today), but is not limited to systems where LTO is in-use.
This exact scenario happened, on FreeBSD, (and OpenBSD): https://github.com/libressl-portable/openbsd/issues/5
(note that someone tested on OpenBSD 5.5 with GCC 4.8.2 from ports, and developed a "patch" that depends on mfence (compiler side-effects):
OpenBSD has not implemented this patch.
If you look at OPENSSL_cleanse() in boringssl, there is a fix for the problem which again, leverages a mfence:
I have prepared and attached a patch for FreeBSD that implements the same memory barrier, solving the problem in a more portable and safe manner.