summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-15 20:16:33 +0000
committerjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-15 20:16:33 +0000
commitb5bf9a135808b579f659d73e6048dd86bc6db903 (patch)
tree221f8bf746cd9ff748511a10cd345ef4f681c527 /third_party
parent49917e8ae1b7f6150fc4347dbfb8b4708262d0a4 (diff)
downloadchromium_src-b5bf9a135808b579f659d73e6048dd86bc6db903.zip
chromium_src-b5bf9a135808b579f659d73e6048dd86bc6db903.tar.gz
chromium_src-b5bf9a135808b579f659d73e6048dd86bc6db903.tar.bz2
TCMalloc: restrict maximum size of memory allocations
For security purposes, we restrict the maximum size of memory allocations under what can be indexed by an int. BUG=169327 NOTRY=true Review URL: https://chromiumcodereview.appspot.com/11857007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176961 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/tcmalloc/chromium/src/tcmalloc.cc56
1 files changed, 35 insertions, 21 deletions
diff --git a/third_party/tcmalloc/chromium/src/tcmalloc.cc b/third_party/tcmalloc/chromium/src/tcmalloc.cc
index 2ff2a3b..591c687 100644
--- a/third_party/tcmalloc/chromium/src/tcmalloc.cc
+++ b/third_party/tcmalloc/chromium/src/tcmalloc.cc
@@ -296,6 +296,16 @@ size_t InvalidGetAllocatedSize(const void* ptr) {
"Attempt to get the size of an invalid pointer", ptr);
return 0;
}
+
+// For security reasons, we want to limit the size of allocations.
+// See crbug.com/169327.
+inline bool IsAllocSizePermitted(size_t alloc_size) {
+ // Never allow an allocation larger than what can be indexed via an int.
+ // Remove kPageSize to account for various rounding, padding and to have a
+ // small margin.
+ return alloc_size <= ((std::numeric_limits<int>::max)() - kPageSize);
+}
+
} // unnamed namespace
// Extract interesting stats
@@ -1078,27 +1088,31 @@ inline void* do_malloc(size_t size) {
// The following call forces module initialization
ThreadCache* heap = ThreadCache::GetCache();
- if (size <= kMaxSize) {
- size_t cl = Static::sizemap()->SizeClass(size);
- size = Static::sizemap()->class_to_size(cl);
-
- // TODO(jar): If this has any detectable performance impact, it can be
- // optimized by only tallying sizes if the profiler was activated to recall
- // these tallies. I don't think this is performance critical, but we really
- // should measure it.
- heap->AddToByteAllocatedTotal(size); // Chromium profiling.
-
- if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) {
- ret = DoSampledAllocation(size);
- MarkAllocatedRegion(ret);
+ // First, check if our security policy allows this size.
+ if (IsAllocSizePermitted(size)) {
+ if (size <= kMaxSize) {
+ size_t cl = Static::sizemap()->SizeClass(size);
+ size = Static::sizemap()->class_to_size(cl);
+
+ // TODO(jar): If this has any detectable performance impact, it can be
+ // optimized by only tallying sizes if the profiler was activated to
+ // recall these tallies. I don't think this is performance critical, but
+ // we really should measure it.
+ heap->AddToByteAllocatedTotal(size); // Chromium profiling.
+
+ if ((FLAGS_tcmalloc_sample_parameter > 0) &&
+ heap->SampleAllocation(size)) {
+ ret = DoSampledAllocation(size);
+ MarkAllocatedRegion(ret);
+ } else {
+ // The common case, and also the simplest. This just pops the
+ // size-appropriate freelist, after replenishing it if it's empty.
+ ret = CheckMallocResult(heap->Allocate(size, cl));
+ }
} else {
- // The common case, and also the simplest. This just pops the
- // size-appropriate freelist, after replenishing it if it's empty.
- ret = CheckMallocResult(heap->Allocate(size, cl));
+ ret = do_malloc_pages(heap, size);
+ MarkAllocatedRegion(ret);
}
- } else {
- ret = do_malloc_pages(heap, size);
- MarkAllocatedRegion(ret);
}
if (ret == NULL) errno = ENOMEM;
return ret;
@@ -1233,8 +1247,8 @@ inline void* do_realloc_with_callback(
// . If we need to grow, grow to max(new_size, old_size * 1.X)
// . Don't shrink unless new_size < old_size * 0.Y
// X and Y trade-off time for wasted space. For now we do 1.25 and 0.5.
- const int lower_bound_to_grow = old_size + old_size / 4;
- const int upper_bound_to_shrink = old_size / 2;
+ const size_t lower_bound_to_grow = old_size + old_size / 4;
+ const size_t upper_bound_to_shrink = old_size / 2;
if ((new_size > old_size) || (new_size < upper_bound_to_shrink)) {
// Need to reallocate.
void* new_ptr = NULL;