1ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes/* 2ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * Copyright (C) 2012 The Android Open Source Project 3ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * 4ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * you may not use this file except in compliance with the License. 6ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * You may obtain a copy of the License at 7ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * 8ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * 10ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * See the License for the specific language governing permissions and 14ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * limitations under the License. 15ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes */ 16ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 17ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes/* 18ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes * Contributed by: Intel Corporation 19ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes */ 20ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 21ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes#include <gtest/gtest.h> 229df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui#include "BionicDeathTest.h" 23ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 24ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes#include <pthread.h> 25ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes#include <stdint.h> 26ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes#include <stdio.h> 27ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes#include <unistd.h> 28ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes#include <set> 29ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 3012393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#include "private/bionic_tls.h" 3112393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes 3212393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughesextern "C" pid_t gettid(); // glibc defines this but doesn't declare it anywhere. 3312393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes 3412393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#if defined(__BIONIC__) 3512393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughesextern uintptr_t __stack_chk_guard; 3612393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#endif 37ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 38ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughesstruct stack_protector_checker { 39ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes std::set<pid_t> tids; 4012393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes std::set<void*> guards; 41ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 42ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes void Check() { 43ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes pid_t tid = gettid(); 4412393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes void* guard = __get_tls()[TLS_SLOT_STACK_GUARD]; 45ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 4612393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes printf("[thread %d] TLS stack guard = %p\n", tid, guard); 47ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 48ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes // Duplicate tid. gettid(2) bug? Seeing this would be very upsetting. 49ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes ASSERT_TRUE(tids.find(tid) == tids.end()); 50d3920b3a996b358e48232f417aa0a1e44a60f155Elliott Hughes 5112393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // Uninitialized guard. Our bug. Note this is potentially flaky; we _could_ 5212393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // get four random zero bytes, but it should be vanishingly unlikely. 5312393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes ASSERT_NE(guard, nullptr); 5412393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes 5512393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#if defined(__BIONIC__) 5612393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // bionic always has the global too. 5712393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes ASSERT_EQ(__stack_chk_guard, reinterpret_cast<uintptr_t>(guard)); 5812393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#endif 59ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 60ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes tids.insert(tid); 61ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes guards.insert(guard); 62ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes } 63ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes}; 64ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 65d3920b3a996b358e48232f417aa0a1e44a60f155Elliott HughesTEST(stack_protector, same_guard_per_thread) { 6612393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // Everyone has the TLS slot set, even if their stack protector 6712393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // implementation doesn't yet use it. 68ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes stack_protector_checker checker; 6912393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes 7012393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // Check the main thread. 7112393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes ASSERT_EQ(getpid(), gettid()); // We are the main thread, right? 7212393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes checker.Check(); 7312393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes 7412393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes size_t thread_count = 9; 7512393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes for (size_t i = 1; i < thread_count; ++i) { 76ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes pthread_t t; 7712393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, [](void* arg) -> void* { 7812393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes stack_protector_checker* checker = reinterpret_cast<stack_protector_checker*>(arg); 7912393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes checker->Check(); 8012393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes return nullptr; 8112393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes }, &checker)); 82ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes void* result; 83ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 84ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes ASSERT_EQ(NULL, result); 85ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes } 86ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes ASSERT_EQ(thread_count, checker.tids.size()); 87ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 8812393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // Both bionic and glibc use the same guard for every thread. 89ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes ASSERT_EQ(1U, checker.guards.size()); 90ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes} 91ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes 92f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher FerrisTEST(stack_protector, global_guard) { 9312393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#if defined(__BIONIC__) 9412393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // Bionic always has a global, even if it's using TLS. 95f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris ASSERT_NE(0, gettid()); 96f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris ASSERT_NE(0U, __stack_chk_guard); 9712393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#else 9812393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes GTEST_LOG_(INFO) << "glibc doesn't have a global __stack_chk_guard.\n"; 9912393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes#endif 100f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris} 101dcab1b2c76a498c56bc00024613386de8b4b2aaeNick Kralevich 1029df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cuiclass stack_protector_DeathTest : public BionicDeathTest {}; 1039df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 1049df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin CuiTEST_F(stack_protector_DeathTest, modify_stack_protector) { 10512393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes // In another file to prevent inlining, which removes stack protection. 10612393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes extern void modify_stack_protector_test(); 10712393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes ASSERT_EXIT(modify_stack_protector_test(), 10812393862e55b9ab28dd29ae16fbdf498371726a7Elliott Hughes testing::KilledBySignal(SIGABRT), "stack corruption detected"); 109dcab1b2c76a498c56bc00024613386de8b4b2aaeNick Kralevich} 110