0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 17:10:48 +01:00

SERVER-19458: Add memory zeroing utility

This commit is contained in:
Spencer Jackson 2015-07-23 17:24:01 -04:00
parent 6fcca346ef
commit 11db3b9b0c
7 changed files with 215 additions and 0 deletions

View File

@ -1718,6 +1718,29 @@ def doConfigure(myenv):
conf.Finish()
def CheckMemset_s(context):
test_body = """
#define __STDC_WANT_LIB_EXT1__ 1
#include <cstring>
int main(int argc, char* argv[]) {
void* data = nullptr;
return memset_s(data, 0, 0, 0);
}
"""
context.Message('Checking for memset_s... ')
ret = context.TryLink(textwrap.dedent(test_body), ".cpp")
context.Result(ret)
return ret
conf = Configure(env, custom_tests = {
'CheckMemset_s' : CheckMemset_s,
})
if conf.CheckMemset_s():
conf.env.SetConfigHeaderDefine("MONGO_CONFIG_HAVE_MEMSET_S")
conf.Finish()
# If we are using libstdc++, check to see if we are using a libstdc++ that is older than
# our GCC minimum of 4.8.2. This is primarly to help people using clang on OS X but
# forgetting to use --libc++ (or set the target OS X version high enough to get it as the

View File

@ -225,6 +225,7 @@ config_header_substs = (
('@mongo_config_have_execinfo_backtrace@', 'MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE'),
('@mongo_config_have_fips_mode_set@', 'MONGO_CONFIG_HAVE_FIPS_MODE_SET'),
('@mongo_config_have_header_unistd_h@', 'MONGO_CONFIG_HAVE_HEADER_UNISTD_H'),
('@mongo_config_have_memset_s@', 'MONGO_CONFIG_HAVE_MEMSET_S'),
('@mongo_config_have_posix_monotonic_clock@', 'MONGO_CONFIG_HAVE_POSIX_MONOTONIC_CLOCK'),
('@mongo_config_have_std_is_trivially_copyable@', 'MONGO_CONFIG_HAVE_STD_IS_TRIVIALLY_COPYABLE'),
('@mongo_config_have_std_make_unique@', 'MONGO_CONFIG_HAVE_STD_MAKE_UNIQUE'),

View File

@ -52,6 +52,9 @@
// Defined if unitstd.h is available
@mongo_config_have_header_unistd_h@
// Defined if memset_s is available
@mongo_config_have_memset_s@
// Defined if a POSIX monotonic clock is available
@mongo_config_have_posix_monotonic_clock@

View File

@ -320,6 +320,24 @@ quick_exit_env.Library(
]
)
env.Library(
target="secure_zero_memory",
source=[
'secure_zero_memory.cpp',
],
LIBDEPS=[
"$BUILD_DIR/mongo/base",
],
)
env.CppUnitTest(
target='secure_zero_memory_test',
source=['secure_zero_memory_test.cpp'],
LIBDEPS=[
'secure_zero_memory'
],
)
if not env.TargetOSIs('windows'):
env.CppUnitTest(
target='signal_handlers_synchronous_test',

View File

@ -0,0 +1,63 @@
/* Copyright 2014 MongoDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*/
#include "mongo/config.h"
#if defined(MONGO_CONFIG_HAVE_MEMSET_S)
#define __STDC_WANT_LIB_EXT1__ 1
#endif
#include "mongo/platform/basic.h"
#include <cstring>
#include "mongo/util/assert_util.h"
namespace mongo {
void secureZeroMemory(void* mem, size_t size) {
if (mem == nullptr) {
fassert(28751, size == 0);
return;
}
#if defined(_WIN32)
// Windows provides a simple function for zeroing memory
SecureZeroMemory(mem, size);
#elif defined(MONGO_CONFIG_HAVE_MEMSET_S)
// Some C11 libraries provide a variant of memset which is guaranteed to not be optimized away
fassert(28752, memset_s(mem, size, 0, size) == 0);
#else
// fall back to using volatile pointer
volatile char* p = reinterpret_cast<volatile char*>(mem);
while (size--) {
*p++ = 0;
}
#endif
}
} // namespace mongo

View File

@ -0,0 +1,43 @@
/* Copyright 2015 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*/
#pragma once
namespace mongo {
/**
* Wrapper around several platform specific methods for zeroing memory
* Memory zeroing is complicated by the fact that compilers will try to optimize it away, as the
* memory frequently will not be later read.
*
* This function will, if available, perform a platform specific operation to zero memory. If no
* platform specific operation is available, memory will be zeroed using volatile pointers.
*/
void secureZeroMemory(void* ptr, size_t size);
} // namespace mongo

View File

@ -0,0 +1,64 @@
/* Copyright 2015 MongoDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*/
#include "mongo/unittest/death_test.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/secure_zero_memory.h"
namespace mongo {
TEST(SecureZeroMemoryTest, zeroZeroLengthNull) {
void* ptr = nullptr;
secureZeroMemory(ptr, 0);
ASSERT_TRUE(true);
}
DEATH_TEST(SecureZeroMemoryTest, zeroNonzeroLengthNull, "Fatal Assertion") {
void* ptr = nullptr;
secureZeroMemory(ptr, 1000);
}
TEST(SecureZeroMemoryTest, dataZeroed) {
static const size_t dataSize = 100;
std::uint8_t data[dataSize];
// Populate array
for (size_t i = 0; i < dataSize; ++i) {
data[i] = i;
}
// Zero array
secureZeroMemory(data, dataSize);
// Check contents
for (size_t i = 0; i < dataSize; ++i) {
ASSERT_FALSE(data[i]);
}
}
} // namespace mongo