1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
11 #include <sys/types.h>
17 #include "base/allocator/buildflags.h"
18 #include "base/files/file_util.h"
19 #include "base/memory/free_deleter.h"
20 #include "base/sanitizer_buildflags.h"
21 #include "build/build_config.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 #if BUILDFLAG(IS_POSIX)
30 using std::numeric_limits;
34 // This function acts as a compiler optimization barrier. We use it to
35 // prevent the compiler from making an expression a compile-time constant.
36 // We also use it so that the compiler doesn't discard certain return values
37 // as something we don't need (see the comment with calloc below).
38 template <typename Type>
39 NOINLINE Type HideValueFromCompiler(Type value) {
41 // In a GCC compatible compiler (GCC or Clang), make this compiler barrier
43 __asm__ volatile ("" : "+r" (value));
48 // There are platforms where these tests are known to fail. We would like to
49 // be able to easily check the status on the bots, but marking tests as
50 // FAILS_ is too clunky.
51 void OverflowTestsSoftExpectTrue(bool overflow_detected) {
52 if (!overflow_detected) {
53 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
55 // Sadly, on Linux, Android, and OSX we don't have a good story yet. Don't
56 // fail the test, but report.
57 printf("Platform has overflow: %s\n",
58 !overflow_detected ? "yes." : "no.");
60 // Otherwise, fail the test. (Note: EXPECT are ok in subfunctions, ASSERT
62 EXPECT_TRUE(overflow_detected);
67 #if BUILDFLAG(IS_APPLE) || defined(ADDRESS_SANITIZER) || \
68 defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
69 BUILDFLAG(IS_HWASAN) || BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
70 #define MAYBE_NewOverflow DISABLED_NewOverflow
72 #define MAYBE_NewOverflow NewOverflow
74 // Test that array[TooBig][X] and array[X][TooBig] allocations fail and not
75 // succeed with the wrong size allocation in case of size_t overflow. This
76 // test is disabled on environments that operator new (nothrow) crashes in
77 // case of size_t overflow.
79 // - iOS doesn't honor nothrow.
80 // - XSan aborts when operator new returns nullptr.
81 // - PartitionAlloc crashes by design when size_t overflows.
83 // TODO(https://crbug.com/927179): Fix the test on Mac.
84 TEST(SecurityTest, MAYBE_NewOverflow) {
85 const size_t kArraySize = 4096;
86 // We want something "dynamic" here, so that the compiler doesn't
87 // immediately reject crazy arrays.
88 [[maybe_unused]] const size_t kDynamicArraySize =
89 HideValueFromCompiler(kArraySize);
90 const size_t kMaxSizeT = std::numeric_limits<size_t>::max();
91 const size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
92 const size_t kDynamicArraySize2 = HideValueFromCompiler(kArraySize2);
94 std::unique_ptr<char[][kArraySize]> array_pointer(
95 new (nothrow) char[kDynamicArraySize2][kArraySize]);
96 // Prevent clang from optimizing away the whole test.
97 char* volatile p = reinterpret_cast<char*>(array_pointer.get());
98 OverflowTestsSoftExpectTrue(!p);
100 #if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)
101 // On Windows, the compiler prevents static array sizes of more than
102 // 0x7fffffff (error C2148).
105 std::unique_ptr<char[][kArraySize2]> array_pointer(
106 new (nothrow) char[kDynamicArraySize][kArraySize2]);
107 // Prevent clang from optimizing away the whole test.
108 char* volatile p = reinterpret_cast<char*>(array_pointer.get());
109 OverflowTestsSoftExpectTrue(!p);
111 #endif // BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)