security_unittest.cc 4.0 KB

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