1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <assert.h> 18 #include <stdint.h> 19 #include <stdlib.h> 20 21 // This library is built for all targets, including host tests, so __cfi_slowpath may not be 22 // present. But it is only used in the bionic loader tests. 23 extern "C" __attribute__((weak)) void __cfi_slowpath(uint64_t, void*); 24 25 static size_t g_count; 26 static uint64_t g_last_type_id; 27 static void* g_last_address; 28 static void* g_last_diag; 29 30 extern "C" { 31 32 // Make sure the library crosses at least one kLibraryAlignment(=256KB) boundary. 33 char bss[1024 * 1024]; 34 35 // Mock a CFI-enabled library without relying on the compiler. 36 __attribute__((aligned(4096))) void __cfi_check(uint64_t CallSiteTypeId, void* TargetAddr, 37 void* Diag) { 38 ++g_count; 39 g_last_type_id = CallSiteTypeId; 40 g_last_address = TargetAddr; 41 g_last_diag = Diag; 42 } 43 44 size_t get_count() { 45 return g_count; 46 } 47 48 uint64_t get_last_type_id() { 49 return g_last_type_id; 50 } 51 52 void* get_last_address() { 53 return g_last_address; 54 } 55 56 void* get_last_diag() { 57 return g_last_diag; 58 } 59 60 void* get_global_address() { 61 return &g_count; 62 } 63 } 64 65 // Check that CFI is set up in module constructors and destructors. 66 struct A { 67 void check_cfi_self() { 68 g_last_type_id = 0; 69 assert(&__cfi_slowpath); 70 // CFI check for an invalid address. Normally, this would kill the process by routing the call 71 // back to the calling module's __cfi_check, which does the right thing based on 72 // -fsanitize-recover / -fsanitize-trap. But this module has custom __cfi_check that does not do 73 // any of that, so the result looks like a passing check. 74 int zz; 75 __cfi_slowpath(13, static_cast<void*>(&zz)); 76 assert(g_last_type_id == 13); 77 // CFI check for a libc function. This never goes into this module's __cfi_check, and must pass. 78 __cfi_slowpath(14, reinterpret_cast<void*>(&exit)); 79 assert(g_last_type_id == 13); 80 } 81 A() { 82 check_cfi_self(); 83 } 84 ~A() { 85 check_cfi_self(); 86 } 87 } a; 88