1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CRAZY_LINKER_ELF_RELRO_H 6 #define CRAZY_LINKER_ELF_RELRO_H 7 8 #include "crazy_linker_ashmem.h" 9 #include "crazy_linker_memory_mapping.h" 10 #include "crazy_linker_system.h" 11 #include "elf_traits.h" 12 13 namespace crazy { 14 15 class ElfView; 16 17 // A class used to model a shared RELRO section backed by an Ashmem region. 18 // The region is always owned by the SharedRelro, unless DetachFd() is called. 19 // The SharedRelro may or may not be mapped into the process. 20 class SharedRelro { 21 public: 22 // Create a new SharedRelro. Note that the object becomes the owner of 23 // |ashmem_fd|, unless DetachFd() is called after this. SharedRelro()24 SharedRelro() : start_(0), size_(0), ashmem_() {} 25 ~SharedRelro()26 ~SharedRelro() {} 27 start()28 size_t start() const { return start_; } end()29 size_t end() const { return start_ + size_; } size()30 size_t size() const { return size_; } fd()31 int fd() const { return ashmem_.fd(); } 32 33 // Return the ashmem region's file descriptor, and detach it from the object. 34 // After this call, fd() will always return -1. DetachFd()35 int DetachFd() { return ashmem_.Release(); } 36 37 // Allocate a new ashmem region of |relro_size| bytes for |library_name|. 38 // This operation doesn't change the process' mappings. On error, return 39 // false and set |error| message. 40 bool Allocate(size_t relro_size, const char* library_name, Error* error); 41 42 // Copy the content of the current process' RELRO into the ashmem region. 43 // |relro_start| is the RELRO address (page-aligned). 44 // |relro_size| is the RELRO size in bytes (page-aligned), and must match 45 // the allocation size passed to Allocate(). 46 // On failure, return false and set |error| message. 47 bool CopyFrom(size_t relro_start, size_t relro_size, Error* error); 48 49 // Copy the contents of the current process' RELRO into the ashmem region 50 // but adjust any relocation targets within it to correspond to a new 51 // |load_address|. |view| must point to a mapped ELF binary for the current 52 // library. |relro_start| corresponds to the address of the current 53 // process' RELRO, i.e. is not relocated. 54 bool CopyFromRelocated(const ElfView* view, 55 size_t load_address, 56 size_t relro_start, 57 size_t relro_size, 58 Error* error); 59 60 // Force the section to be read-only. 61 bool ForceReadOnly(Error* error); 62 63 // Map the ashmem region's pages into the current process, doing a comparison 64 // to avoid corrupting parts of the RELRO section that are different in this 65 // one (e.g. due to symbolic relocations to randomized system libraries). 66 // This operation is _not_ atomic, i.e. no other thread should try to execute 67 // code that reads from the RELRO region during this call. 68 // On failure, return false and set |error| message. 69 // This operation does not transfer ownership of |ashmem_fd| to the object. 70 bool InitFrom(size_t relro_start, 71 size_t relro_size, 72 int ashmem_fd, 73 Error* error); 74 75 private: 76 size_t start_; 77 size_t size_; 78 AshmemRegion ashmem_; 79 }; 80 81 } // namespace crazy 82 83 #endif // CRAZY_LINKER_ELF_RELRO_H 84