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:
parent
6fcca346ef
commit
11db3b9b0c
23
SConstruct
23
SConstruct
@ -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
|
||||
|
@ -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'),
|
||||
|
@ -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@
|
||||
|
||||
|
@ -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',
|
||||
|
63
src/mongo/util/secure_zero_memory.cpp
Normal file
63
src/mongo/util/secure_zero_memory.cpp
Normal 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
|
43
src/mongo/util/secure_zero_memory.h
Normal file
43
src/mongo/util/secure_zero_memory.h
Normal 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
|
64
src/mongo/util/secure_zero_memory_test.cpp
Normal file
64
src/mongo/util/secure_zero_memory_test.cpp
Normal 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
|
Loading…
Reference in New Issue
Block a user