1 // Copyright 2021 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. 4 5 #include "base/stack_canary_linux.h" 6 7 #include "base/compiler_specific.h" 8 #include "build/build_config.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace base { 12 13 #if defined(LIBC_GLIBC) && \ 14 (defined(ARCH_CPU_ARM_FAMILY) || defined(ARCH_CPU_X86_FAMILY)) 15 16 namespace { ResetCanaryAndReturn()17NOINLINE NOOPT void ResetCanaryAndReturn() { 18 // Create a buffer >=8 bytes to force the stack protector on this function, 19 // which should work as long as -fno-stack-protector isn't passed in the 20 // default options. We compile this file with -fstack-protector-all, but it 21 // may be overridden with -fstack-protector or -fstack-protector-strong. 22 [[maybe_unused]] char buffer[10]; 23 ResetStackCanaryIfPossible(); 24 } 25 } // namespace 26 27 // Essentially tests that ResetStackCanaryIfPossible() changes the 28 // actual reference canary that is checked in the function prologue. TEST(StackCanary,ChangingStackCanaryCrashesOnReturn)29TEST(StackCanary, ChangingStackCanaryCrashesOnReturn) { 30 ASSERT_DEATH(ResetCanaryAndReturn(), "stack smashing"); 31 } 32 33 #if !defined(NDEBUG) 34 // Tests that the useful debug message works--specifically that on death, it 35 // prints out the bug URL with useful information. TEST(StackCanary,ChangingStackCanaryPrintsDebugMessage)36TEST(StackCanary, ChangingStackCanaryPrintsDebugMessage) { 37 SetStackSmashingEmitsDebugMessage(); 38 ASSERT_DEATH(ResetCanaryAndReturn(), "crbug\\.com/1206626"); 39 } 40 #endif // !defined(NDEBUG) 41 42 #endif // defined(LIBC_GLIBC) && (defined(ARCH_CPU_ARM_FAMILY) || 43 // defined(ARCH_CPU_X86_FAMILY)) 44 45 } // namespace base 46