Home | History | Annotate | Download | only in src
      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.
     24   SharedRelro() : start_(0), size_(0), ashmem_() {}
     25 
     26   ~SharedRelro() {}
     27 
     28   size_t start() const { return start_; }
     29   size_t end() const { return start_ + size_; }
     30   size_t size() const { return size_; }
     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.
     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