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. __cfi_check(uint64_t CallSiteTypeId,void * TargetAddr,void * Diag)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 get_count()44 size_t get_count() { 45 return g_count; 46 } 47 get_last_type_id()48 uint64_t get_last_type_id() { 49 return g_last_type_id; 50 } 51 get_last_address()52 void* get_last_address() { 53 return g_last_address; 54 } 55 get_last_diag()56 void* get_last_diag() { 57 return g_last_diag; 58 } 59 get_global_address()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 { check_cfi_selfA67 void check_cfi_self() { 68 g_last_type_id = 0; 69 assert(&__cfi_slowpath); 70 // CFI check for an address inside this DSO. This goes to the current module's __cfi_check, 71 // which updates g_last_type_id. 72 __cfi_slowpath(13, static_cast<void*>(&g_last_type_id)); 73 assert(g_last_type_id == 13); 74 // CFI check for a libc function. This never goes into this module's __cfi_check, and must pass. 75 __cfi_slowpath(14, reinterpret_cast<void*>(&exit)); 76 assert(g_last_type_id == 13); 77 } AA78 A() { 79 check_cfi_self(); 80 } ~AA81 ~A() { 82 check_cfi_self(); 83 } 84 } a; 85