Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(758)

Unified Diff: base/security_unittest.cc

Issue 774683003: Remove tcmalloc when not being used. Restore shim on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add realloc death test. nits. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/profiler/alternate_timer.cc ('k') | build/common.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/security_unittest.cc
diff --git a/base/security_unittest.cc b/base/security_unittest.cc
index d786273c023aa1fbdf33c834f718d07eab057656..a7e3bc4bd6e72e95097fa198702337a7664fc7ac 100644
--- a/base/security_unittest.cc
+++ b/base/security_unittest.cc
@@ -23,11 +23,46 @@
#include <unistd.h>
#endif
+#if defined(OS_WIN)
+#include <new.h>
+#endif
+
using std::nothrow;
using std::numeric_limits;
namespace {
+#if defined(OS_WIN)
+// This is a permitted size but exhausts memory pretty quickly.
+const size_t kLargePermittedAllocation = 0x7FFFE000;
+
+int OnNoMemory(size_t) {
+ _exit(1);
+}
+
+void ExhaustMemoryWithMalloc() {
+ for (;;) {
+ void* buf = malloc(kLargePermittedAllocation);
+ if (!buf)
+ break;
+ }
+}
+
+void ExhaustMemoryWithRealloc() {
+ size_t size = kLargePermittedAllocation;
+ void* buf = malloc(size);
+ if (!buf)
+ return;
+ for (;;) {
+ size += kLargePermittedAllocation;
+ void* new_buf = realloc(buf, size);
+ if (!buf)
+ break;
+ buf = new_buf;
+ }
+}
+#endif
+
// This function acts as a compiler optimization barrier. We use it to
// prevent the compiler from making an expression a compile-time constant.
// We also use it so that the compiler doesn't discard certain return values
@@ -42,15 +77,18 @@ Type HideValueFromCompiler(volatile Type value) {
return value;
}
+// Tcmalloc and Windows allocator shim support setting malloc limits.
// - NO_TCMALLOC (should be defined if compiled with use_allocator!="tcmalloc")
// - ADDRESS_SANITIZER and SYZYASAN because they have their own memory allocator
// - IOS does not use tcmalloc
// - OS_MACOSX does not use tcmalloc
-#if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \
- !defined(OS_IOS) && !defined(OS_MACOSX) && !defined(SYZYASAN)
- #define TCMALLOC_TEST(function) function
+// - Windows allocator shim defines ALLOCATOR_SHIM
+#if (!defined(NO_TCMALLOC) || defined(ALLOCATOR_SHIM)) && \
+ !defined(ADDRESS_SANITIZER) && !defined(OS_IOS) && !defined(OS_MACOSX) && \
+ !defined(SYZYASAN)
+#define MALLOC_OVERFLOW_TEST(function) function
#else
- #define TCMALLOC_TEST(function) DISABLED_##function
+#define MALLOC_OVERFLOW_TEST(function) DISABLED_##function
#endif
// TODO(jln): switch to std::numeric_limits<int>::max() when we switch to
@@ -64,12 +102,6 @@ bool IsTcMallocBypassed() {
char* g_slice = getenv("G_SLICE");
if (g_slice && !strcmp(g_slice, "always-malloc"))
return true;
-#elif defined(OS_WIN)
- // This should detect a TCMalloc bypass from setting
- // the CHROME_ALLOCATOR environment variable.
- char* allocator = getenv("CHROME_ALLOCATOR");
- if (allocator && strcmp(allocator, "tcmalloc"))
- return true;
#endif
return false;
}
@@ -89,7 +121,7 @@ bool CallocDiesOnOOM() {
}
// Fake test that allow to know the state of TCMalloc by looking at bots.
-TEST(SecurityTest, TCMALLOC_TEST(IsTCMallocDynamicallyBypassed)) {
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(IsTCMallocDynamicallyBypassed)) {
printf("Malloc is dynamically bypassed: %s\n",
IsTcMallocBypassed() ? "yes." : "no.");
}
@@ -99,7 +131,7 @@ TEST(SecurityTest, TCMALLOC_TEST(IsTCMallocDynamicallyBypassed)) {
// vulnerabilities in libraries that use int instead of size_t. See
// crbug.com/169327.
-TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsMalloc)) {
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsMalloc)) {
if (!IsTcMallocBypassed()) {
scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
HideValueFromCompiler(malloc(kTooBigAllocSize))));
@@ -107,7 +139,43 @@ TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsMalloc)) {
}
}
-TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsCalloc)) {
+#if defined(GTEST_HAS_DEATH_TEST) && defined(OS_WIN)
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationMallocDeathTest)) {
+ _set_new_handler(&OnNoMemory);
+ _set_new_mode(1);
+ {
+ scoped_ptr<char, base::FreeDeleter> ptr;
+ EXPECT_DEATH(ptr.reset(static_cast<char*>(
+ HideValueFromCompiler(malloc(kTooBigAllocSize)))),
+ "");
+ ASSERT_TRUE(!ptr);
+ }
+ _set_new_handler(NULL);
+ _set_new_mode(0);
+}
+
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationExhaustDeathTest)) {
+ _set_new_handler(&OnNoMemory);
+ _set_new_mode(1);
+ {
+ ASSERT_DEATH(ExhaustMemoryWithMalloc(), "");
+ }
+ _set_new_handler(NULL);
+ _set_new_mode(0);
+}
+
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryReallocationExhaustDeathTest)) {
+ _set_new_handler(&OnNoMemory);
+ _set_new_mode(1);
+ {
+ ASSERT_DEATH(ExhaustMemoryWithRealloc(), "");
+ }
+ _set_new_handler(NULL);
+ _set_new_mode(0);
+}
+#endif
+
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsCalloc)) {
if (!IsTcMallocBypassed()) {
scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
HideValueFromCompiler(calloc(kTooBigAllocSize, 1))));
@@ -115,7 +183,7 @@ TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsCalloc)) {
}
}
-TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsRealloc)) {
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsRealloc)) {
if (!IsTcMallocBypassed()) {
char* orig_ptr = static_cast<char*>(malloc(1));
ASSERT_TRUE(orig_ptr);
@@ -131,7 +199,7 @@ typedef struct {
char large_array[kTooBigAllocSize];
} VeryLargeStruct;
-TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNew)) {
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsNew)) {
if (!IsTcMallocBypassed()) {
scoped_ptr<VeryLargeStruct> ptr(
HideValueFromCompiler(new (nothrow) VeryLargeStruct));
@@ -139,7 +207,20 @@ TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNew)) {
}
}
-TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNewArray)) {
+#if defined(GTEST_HAS_DEATH_TEST) && defined(OS_WIN)
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationNewDeathTest)) {
+ _set_new_handler(&OnNoMemory);
+ {
+ scoped_ptr<VeryLargeStruct> ptr;
+ EXPECT_DEATH(
+ ptr.reset(HideValueFromCompiler(new (nothrow) VeryLargeStruct)), "");
+ ASSERT_TRUE(!ptr);
+ }
+ _set_new_handler(NULL);
+}
+#endif
+
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsNewArray)) {
if (!IsTcMallocBypassed()) {
scoped_ptr<char[]> ptr(
HideValueFromCompiler(new (nothrow) char[kTooBigAllocSize]));
@@ -242,7 +323,7 @@ bool ArePointersToSameArea(void* ptr1, void* ptr2, size_t size) {
}
// Check if TCMalloc uses an underlying random memory allocator.
-TEST(SecurityTest, TCMALLOC_TEST(RandomMemoryAllocations)) {
+TEST(SecurityTest, MALLOC_OVERFLOW_TEST(RandomMemoryAllocations)) {
if (IsTcMallocBypassed())
return;
size_t kPageSize = 4096; // We support x86_64 only.
« no previous file with comments | « base/profiler/alternate_timer.cc ('k') | build/common.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698