// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CRAZY_LINKER_ELF_RELRO_H #define CRAZY_LINKER_ELF_RELRO_H #include "crazy_linker_ashmem.h" #include "crazy_linker_memory_mapping.h" #include "crazy_linker_system.h" #include "elf_traits.h" namespace crazy { class ElfView; // A class used to model a shared RELRO section backed by an Ashmem region. // The region is always owned by the SharedRelro, unless DetachFd() is called. // The SharedRelro may or may not be mapped into the process. class SharedRelro { public: // Create a new SharedRelro. Note that the object becomes the owner of // |ashmem_fd|, unless DetachFd() is called after this. SharedRelro() : start_(0), size_(0), ashmem_() {} ~SharedRelro() {} size_t start() const { return start_; } size_t end() const { return start_ + size_; } size_t size() const { return size_; } int fd() const { return ashmem_.fd(); } // Return the ashmem region's file descriptor, and detach it from the object. // After this call, fd() will always return -1. int DetachFd() { return ashmem_.Release(); } // Allocate a new ashmem region of |relro_size| bytes for |library_name|. // This operation doesn't change the process' mappings. On error, return // false and set |error| message. bool Allocate(size_t relro_size, const char* library_name, Error* error); // Copy the content of the current process' RELRO into the ashmem region. // |relro_start| is the RELRO address (page-aligned). // |relro_size| is the RELRO size in bytes (page-aligned), and must match // the allocation size passed to Allocate(). // On failure, return false and set |error| message. bool CopyFrom(size_t relro_start, size_t relro_size, Error* error); // Copy the contents of the current process' RELRO into the ashmem region // but adjust any relocation targets within it to correspond to a new // |load_address|. |view| must point to a mapped ELF binary for the current // library. |relro_start| corresponds to the address of the current // process' RELRO, i.e. is not relocated. bool CopyFromRelocated(const ElfView* view, size_t load_address, size_t relro_start, size_t relro_size, Error* error); // Force the section to be read-only. bool ForceReadOnly(Error* error); // Map the ashmem region's pages into the current process, doing a comparison // to avoid corrupting parts of the RELRO section that are different in this // one (e.g. due to symbolic relocations to randomized system libraries). // This operation is _not_ atomic, i.e. no other thread should try to execute // code that reads from the RELRO region during this call. // On failure, return false and set |error| message. // This operation does not transfer ownership of |ashmem_fd| to the object. bool InitFrom(size_t relro_start, size_t relro_size, int ashmem_fd, Error* error); private: size_t start_; size_t size_; AshmemRegion ashmem_; }; } // namespace crazy #endif // CRAZY_LINKER_ELF_RELRO_H