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