Switch memory_cleanse implementation to BoringSSL's to ensure memory clearing even with link-time optimization.
The implementation we currently use from OpenSSL prevents the compiler from optimizing away clensing operations on blocks of memory that are about to be released, but this protection is not extended to link-time optimization. This commit copies the solution cooked up by Google compiler engineers which uses inline assembly directives to instruct the compiler not to optimize out the call under any circumstances. As the code is in-lined, this has the added advantage of removing one more OpenSSL dependency. Regarding license compatibility, Google's contributions to BoringSSL library, including this code, is made available under the ISC license, which is MIT compatible. BoringSSL git commit: ad1907fe73334d6c696c8539646c21b11178f20f
This commit is contained in:
parent
961901f77e
commit
1444c2e7d0
1 changed files with 28 additions and 2 deletions
|
@ -5,9 +5,35 @@
|
|||
|
||||
#include "cleanse.h"
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <cstring>
|
||||
|
||||
/* Compilers have a bad habit of removing "superfluous" memset calls that
|
||||
* are trying to zero memory. For example, when memset()ing a buffer and
|
||||
* then free()ing it, the compiler might decide that the memset is
|
||||
* unobservable and thus can be removed.
|
||||
*
|
||||
* Previously we used OpenSSL which tried to stop this by a) implementing
|
||||
* memset in assembly on x86 and b) putting the function in its own file
|
||||
* for other platforms.
|
||||
*
|
||||
* This change removes those tricks in favour of using asm directives to
|
||||
* scare the compiler away. As best as our compiler folks can tell, this is
|
||||
* sufficient and will continue to be so.
|
||||
*
|
||||
* Adam Langley <agl@google.com>
|
||||
* Commit: ad1907fe73334d6c696c8539646c21b11178f20f
|
||||
* BoringSSL (LICENSE: ISC)
|
||||
*/
|
||||
void memory_cleanse(void *ptr, size_t len)
|
||||
{
|
||||
OPENSSL_cleanse(ptr, len);
|
||||
std::memset(ptr, 0, len);
|
||||
|
||||
/* As best as we can tell, this is sufficient to break any optimisations that
|
||||
might try to eliminate "superfluous" memsets. If there's an easy way to
|
||||
detect memset_s, it would be better to use that. */
|
||||
#if defined(_MSC_VER)
|
||||
__asm;
|
||||
#else
|
||||
__asm__ __volatile__("" : : "r"(ptr) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue