1*8d67ca89SAndroid Build Coastguard Worker /* 2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*8d67ca89SAndroid Build Coastguard Worker * 4*8d67ca89SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*8d67ca89SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*8d67ca89SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*8d67ca89SAndroid Build Coastguard Worker * 8*8d67ca89SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*8d67ca89SAndroid Build Coastguard Worker * 10*8d67ca89SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*8d67ca89SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*8d67ca89SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*8d67ca89SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*8d67ca89SAndroid Build Coastguard Worker * limitations under the License. 15*8d67ca89SAndroid Build Coastguard Worker */ 16*8d67ca89SAndroid Build Coastguard Worker 17*8d67ca89SAndroid Build Coastguard Worker #ifndef CFI_SHADOW_H 18*8d67ca89SAndroid Build Coastguard Worker #define CFI_SHADOW_H 19*8d67ca89SAndroid Build Coastguard Worker 20*8d67ca89SAndroid Build Coastguard Worker #include <stdint.h> 21*8d67ca89SAndroid Build Coastguard Worker 22*8d67ca89SAndroid Build Coastguard Worker #include "platform/bionic/page.h" 23*8d67ca89SAndroid Build Coastguard Worker #include "platform/bionic/macros.h" 24*8d67ca89SAndroid Build Coastguard Worker 25*8d67ca89SAndroid Build Coastguard Worker constexpr unsigned kLibraryAlignmentBits = 18; 26*8d67ca89SAndroid Build Coastguard Worker constexpr size_t kLibraryAlignment = 1UL << kLibraryAlignmentBits; 27*8d67ca89SAndroid Build Coastguard Worker 28*8d67ca89SAndroid Build Coastguard Worker // This class defines format of the shadow region for Control Flow Integrity support. 29*8d67ca89SAndroid Build Coastguard Worker // See documentation in http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html#shared-library-support. 30*8d67ca89SAndroid Build Coastguard Worker // 31*8d67ca89SAndroid Build Coastguard Worker // CFI shadow is effectively a very fast and specialized implementation of dladdr: given an address that 32*8d67ca89SAndroid Build Coastguard Worker // belongs to a shared library or an executable, it can find the address of a specific export in that 33*8d67ca89SAndroid Build Coastguard Worker // library (a function called "__cfi_check"). This is only guaranteed to work for 34*8d67ca89SAndroid Build Coastguard Worker // addresses of possible CFI targets inside a library: indirectly called functions and virtual 35*8d67ca89SAndroid Build Coastguard Worker // tables. A random address inside a library may not work in the future (but it does in the current 36*8d67ca89SAndroid Build Coastguard Worker // implementation). 37*8d67ca89SAndroid Build Coastguard Worker // 38*8d67ca89SAndroid Build Coastguard Worker // Implementation is a sparse array of uint16_t where each element describes the location of 39*8d67ca89SAndroid Build Coastguard Worker // __cfi_check for a 2**kShadowGranularity range of memory. Array elements (called "shadow values" 40*8d67ca89SAndroid Build Coastguard Worker // below) are interpreted as follows. 41*8d67ca89SAndroid Build Coastguard Worker // 42*8d67ca89SAndroid Build Coastguard Worker // For an address P and corresponding shadow value V, the address of __cfi_check is calculated as 43*8d67ca89SAndroid Build Coastguard Worker // align_up(P, 2**kShadowGranularity) - (V - 2) * (2 ** kCfiCheckGranularity) 44*8d67ca89SAndroid Build Coastguard Worker // 45*8d67ca89SAndroid Build Coastguard Worker // Special shadow values: 46*8d67ca89SAndroid Build Coastguard Worker // 0 = kInvalidShadow, this memory range has no valid CFI targets. 47*8d67ca89SAndroid Build Coastguard Worker // 1 = kUncheckedShadow, any address is this memory range is a valid CFI target 48*8d67ca89SAndroid Build Coastguard Worker // 49*8d67ca89SAndroid Build Coastguard Worker // Loader requirement: each aligned 2**kShadowGranularity region of address space may contain at 50*8d67ca89SAndroid Build Coastguard Worker // most one DSO. 51*8d67ca89SAndroid Build Coastguard Worker // Compiler requirement: __cfi_check is aligned at kCfiCheckGranularity. 52*8d67ca89SAndroid Build Coastguard Worker // Compiler requirement: __cfi_check for a given DSO is located below any CFI target for that DSO. 53*8d67ca89SAndroid Build Coastguard Worker class CFIShadow { 54*8d67ca89SAndroid Build Coastguard Worker public: 55*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t kShadowGranularity = kLibraryAlignmentBits; 56*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t kCfiCheckGranularity = 12; 57*8d67ca89SAndroid Build Coastguard Worker 58*8d67ca89SAndroid Build Coastguard Worker // Each uint16_t element of the shadow corresponds to this much application memory. 59*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t kShadowAlign = 1UL << kShadowGranularity; 60*8d67ca89SAndroid Build Coastguard Worker 61*8d67ca89SAndroid Build Coastguard Worker // Alignment of __cfi_check. 62*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t kCfiCheckAlign = 1UL << kCfiCheckGranularity; // 4K 63*8d67ca89SAndroid Build Coastguard Worker 64*8d67ca89SAndroid Build Coastguard Worker #if defined (__LP64__) 65*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t kMaxTargetAddr = 0xffffffffffff; 66*8d67ca89SAndroid Build Coastguard Worker #else 67*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t kMaxTargetAddr = 0xffffffff; 68*8d67ca89SAndroid Build Coastguard Worker #endif 69*8d67ca89SAndroid Build Coastguard Worker 70*8d67ca89SAndroid Build Coastguard Worker // Shadow is 2 -> 2**kShadowGranularity. 71*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t kShadowSize = kMaxTargetAddr >> (kShadowGranularity - 1); 72*8d67ca89SAndroid Build Coastguard Worker 73*8d67ca89SAndroid Build Coastguard Worker // Returns offset inside the shadow region for an address. MemToShadowOffset(uintptr_t x)74*8d67ca89SAndroid Build Coastguard Worker static constexpr uintptr_t MemToShadowOffset(uintptr_t x) { 75*8d67ca89SAndroid Build Coastguard Worker return (x >> kShadowGranularity) << 1; 76*8d67ca89SAndroid Build Coastguard Worker } 77*8d67ca89SAndroid Build Coastguard Worker 78*8d67ca89SAndroid Build Coastguard Worker typedef int (*CFICheckFn)(uint64_t, void *, void *); 79*8d67ca89SAndroid Build Coastguard Worker 80*8d67ca89SAndroid Build Coastguard Worker public: 81*8d67ca89SAndroid Build Coastguard Worker enum ShadowValues : uint16_t { 82*8d67ca89SAndroid Build Coastguard Worker kInvalidShadow = 0, // Not a valid CFI target. 83*8d67ca89SAndroid Build Coastguard Worker kUncheckedShadow = 1, // Unchecked, valid CFI target. 84*8d67ca89SAndroid Build Coastguard Worker kRegularShadowMin = 2 // This and all higher values encode a negative offset to __cfi_check in 85*8d67ca89SAndroid Build Coastguard Worker // the units of kCfiCheckGranularity, starting with 0 at 86*8d67ca89SAndroid Build Coastguard Worker // kRegularShadowMin. 87*8d67ca89SAndroid Build Coastguard Worker }; 88*8d67ca89SAndroid Build Coastguard Worker }; 89*8d67ca89SAndroid Build Coastguard Worker 90*8d67ca89SAndroid Build Coastguard Worker #endif // CFI_SHADOW_H 91