| Index: base/security_unittest.cc
|
| diff --git a/base/security_unittest.cc b/base/security_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..91969ce34cc2f766ca8995002145f63c016211fd
|
| --- /dev/null
|
| +++ b/base/security_unittest.cc
|
| @@ -0,0 +1,70 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <algorithm>
|
| +#include <limits>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace {
|
| +
|
| +// TODO(jln): list instead the known cases that fail (ASAN etc), so that
|
| +// we can positively check that we support the cases we care about.
|
| +#if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER)
|
| + #define MAYBE(function) function
|
| +#else
|
| + #define MAYBE(function) DISABLED_##function
|
| +#endif
|
| +
|
| +// Check that we can not allocate a memory range that cannot be indexed
|
| +// via an int. This is used to mitigate vulnerabilities in libraries that use
|
| +// int instead of size_t.
|
| +// See crbug.com/169327.
|
| +
|
| +// TODO(jln): make this a static constant when we switch to C++11.
|
| +size_t MaximumAllocSize() {
|
| + return std::numeric_limits<int>::max();
|
| +}
|
| +
|
| +TEST(SecurityTest, MAYBE(MemoryAllocationRestrictionsOneAlloc)) {
|
| + scoped_ptr<char, base::FreeDeleter>
|
| + ptr(static_cast<char*>(malloc(MaximumAllocSize())));
|
| + ASSERT_TRUE(ptr == NULL);
|
| +}
|
| +
|
| +// This would be a test for a much stricter restriction preventing a contiguous
|
| +// memory area of size MaximumAllocSize to be allocated via malloc.
|
| +// Implementing this requires more effort and the test is disabled.
|
| +TEST(SecurityTest, DISABLED_MemoryAllocationRestrictionsStepped) {
|
| + const int kAllocNumber = 8;
|
| + const size_t kSteppedAllocSize = MaximumAllocSize() / kAllocNumber;
|
| + // Allow 1/32th for MetaData and padding.
|
| + const size_t kExpectedExtra = kSteppedAllocSize >> 5;
|
| +
|
| + bool is_contiguous = true;
|
| + // Make kAllocNumber successive allocations and compare the successive
|
| + // pointers to detect adjacent mappings.
|
| + scoped_ptr<char, base::FreeDeleter> ptr[kAllocNumber];
|
| + for (int i = 0; i < kAllocNumber; ++i) {
|
| + ptr[i].reset(static_cast<char*>(malloc(kSteppedAllocSize)));
|
| + if (ptr[i] == NULL) {
|
| + is_contiguous = false;
|
| + break;
|
| + }
|
| + if (i > 0) {
|
| + size_t pointer_diff = static_cast<size_t>(
|
| + std::max(ptr[i].get(), ptr[i - 1].get()) -
|
| + std::min(ptr[i].get(), ptr[i - 1].get()));
|
| + if (pointer_diff > (kSteppedAllocSize + kExpectedExtra)) {
|
| + is_contiguous = false;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + ASSERT_FALSE(is_contiguous);
|
| +}
|
| +
|
| +} // namespace
|
|
|