Home | History | Annotate | Download | only in libunwindstack
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <errno.h>
     18 #include <fcntl.h>
     19 #include <sys/mman.h>
     20 #include <sys/ptrace.h>
     21 #include <sys/stat.h>
     22 #include <sys/types.h>
     23 #include <sys/uio.h>
     24 #include <unistd.h>
     25 
     26 #include <algorithm>
     27 #include <memory>
     28 
     29 #include <android-base/unique_fd.h>
     30 
     31 #include <unwindstack/Memory.h>
     32 
     33 #include "Check.h"
     34 
     35 namespace unwindstack {
     36 
     37 bool Memory::ReadString(uint64_t addr, std::string* string, uint64_t max_read) {
     38   string->clear();
     39   uint64_t bytes_read = 0;
     40   while (bytes_read < max_read) {
     41     uint8_t value;
     42     if (!Read(addr, &value, sizeof(value))) {
     43       return false;
     44     }
     45     if (value == '\0') {
     46       return true;
     47     }
     48     string->push_back(value);
     49     addr++;
     50     bytes_read++;
     51   }
     52   return false;
     53 }
     54 
     55 bool MemoryBuffer::Read(uint64_t addr, void* dst, size_t size) {
     56   uint64_t last_read_byte;
     57   if (__builtin_add_overflow(size, addr, &last_read_byte)) {
     58     return false;
     59   }
     60   if (last_read_byte > raw_.size()) {
     61     return false;
     62   }
     63   memcpy(dst, &raw_[addr], size);
     64   return true;
     65 }
     66 
     67 uint8_t* MemoryBuffer::GetPtr(size_t offset) {
     68   if (offset < raw_.size()) {
     69     return &raw_[offset];
     70   }
     71   return nullptr;
     72 }
     73 
     74 MemoryFileAtOffset::~MemoryFileAtOffset() {
     75   Clear();
     76 }
     77 
     78 void MemoryFileAtOffset::Clear() {
     79   if (data_) {
     80     munmap(&data_[-offset_], size_ + offset_);
     81     data_ = nullptr;
     82   }
     83 }
     84 
     85 bool MemoryFileAtOffset::Init(const std::string& file, uint64_t offset, uint64_t size) {
     86   // Clear out any previous data if it exists.
     87   Clear();
     88 
     89   android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(file.c_str(), O_RDONLY | O_CLOEXEC)));
     90   if (fd == -1) {
     91     return false;
     92   }
     93   struct stat buf;
     94   if (fstat(fd, &buf) == -1) {
     95     return false;
     96   }
     97   if (offset >= static_cast<uint64_t>(buf.st_size)) {
     98     return false;
     99   }
    100 
    101   offset_ = offset & (getpagesize() - 1);
    102   uint64_t aligned_offset = offset & ~(getpagesize() - 1);
    103   if (aligned_offset > static_cast<uint64_t>(buf.st_size) ||
    104       offset > static_cast<uint64_t>(buf.st_size)) {
    105     return false;
    106   }
    107 
    108   size_ = buf.st_size - aligned_offset;
    109   uint64_t max_size;
    110   if (!__builtin_add_overflow(size, offset_, &max_size) && max_size < size_) {
    111     // Truncate the mapped size.
    112     size_ = max_size;
    113   }
    114   void* map = mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, fd, aligned_offset);
    115   if (map == MAP_FAILED) {
    116     return false;
    117   }
    118 
    119   data_ = &reinterpret_cast<uint8_t*>(map)[offset_];
    120   size_ -= offset_;
    121 
    122   return true;
    123 }
    124 
    125 bool MemoryFileAtOffset::Read(uint64_t addr, void* dst, size_t size) {
    126   uint64_t max_size;
    127   if (__builtin_add_overflow(addr, size, &max_size) || max_size > size_) {
    128     return false;
    129   }
    130   memcpy(dst, &data_[addr], size);
    131   return true;
    132 }
    133 
    134 bool MemoryRemote::PtraceRead(uint64_t addr, long* value) {
    135 #if !defined(__LP64__)
    136   // Cannot read an address greater than 32 bits.
    137   if (addr > UINT32_MAX) {
    138     return false;
    139   }
    140 #endif
    141   // ptrace() returns -1 and sets errno when the operation fails.
    142   // To disambiguate -1 from a valid result, we clear errno beforehand.
    143   errno = 0;
    144   *value = ptrace(PTRACE_PEEKTEXT, pid_, reinterpret_cast<void*>(addr), nullptr);
    145   if (*value == -1 && errno) {
    146     return false;
    147   }
    148   return true;
    149 }
    150 
    151 bool MemoryRemote::Read(uint64_t addr, void* dst, size_t bytes) {
    152   // Make sure that there is no overflow.
    153   uint64_t max_size;
    154   if (__builtin_add_overflow(addr, bytes, &max_size)) {
    155     return false;
    156   }
    157 
    158   size_t bytes_read = 0;
    159   long data;
    160   size_t align_bytes = addr & (sizeof(long) - 1);
    161   if (align_bytes != 0) {
    162     if (!PtraceRead(addr & ~(sizeof(long) - 1), &data)) {
    163       return false;
    164     }
    165     size_t copy_bytes = std::min(sizeof(long) - align_bytes, bytes);
    166     memcpy(dst, reinterpret_cast<uint8_t*>(&data) + align_bytes, copy_bytes);
    167     addr += copy_bytes;
    168     dst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(dst) + copy_bytes);
    169     bytes -= copy_bytes;
    170     bytes_read += copy_bytes;
    171   }
    172 
    173   for (size_t i = 0; i < bytes / sizeof(long); i++) {
    174     if (!PtraceRead(addr, &data)) {
    175       return false;
    176     }
    177     memcpy(dst, &data, sizeof(long));
    178     dst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(dst) + sizeof(long));
    179     addr += sizeof(long);
    180     bytes_read += sizeof(long);
    181   }
    182 
    183   size_t left_over = bytes & (sizeof(long) - 1);
    184   if (left_over) {
    185     if (!PtraceRead(addr, &data)) {
    186       return false;
    187     }
    188     memcpy(dst, &data, left_over);
    189     bytes_read += left_over;
    190   }
    191   return true;
    192 }
    193 
    194 bool MemoryLocal::Read(uint64_t addr, void* dst, size_t size) {
    195   // Make sure that there is no overflow.
    196   uint64_t max_size;
    197   if (__builtin_add_overflow(addr, size, &max_size)) {
    198     return false;
    199   }
    200 
    201   // The process_vm_readv call will not always work on remote
    202   // processes, so only use it for reads from the current pid.
    203   // Use this method to avoid crashes if an address is invalid since
    204   // unwind data could try to access any part of the address space.
    205   struct iovec local_io;
    206   local_io.iov_base = dst;
    207   local_io.iov_len = size;
    208 
    209   struct iovec remote_io;
    210   remote_io.iov_base = reinterpret_cast<void*>(static_cast<uintptr_t>(addr));
    211   remote_io.iov_len = size;
    212 
    213   ssize_t bytes_read = process_vm_readv(getpid(), &local_io, 1, &remote_io, 1, 0);
    214   if (bytes_read == -1) {
    215     return false;
    216   }
    217   return static_cast<size_t>(bytes_read) == size;
    218 }
    219 
    220 bool MemoryOffline::Init(const std::string& file, uint64_t offset) {
    221   if (!MemoryFileAtOffset::Init(file, offset)) {
    222     return false;
    223   }
    224   // The first uint64_t value is the start of memory.
    225   if (!MemoryFileAtOffset::Read(0, &start_, sizeof(start_))) {
    226     return false;
    227   }
    228   // Subtract the first 64 bit value from the total size.
    229   size_ -= sizeof(start_);
    230   return true;
    231 }
    232 
    233 bool MemoryOffline::Read(uint64_t addr, void* dst, size_t size) {
    234   uint64_t max_size;
    235   if (__builtin_add_overflow(addr, size, &max_size)) {
    236     return false;
    237   }
    238 
    239   uint64_t real_size;
    240   if (__builtin_add_overflow(start_, offset_, &real_size) ||
    241       __builtin_add_overflow(real_size, size_, &real_size)) {
    242     return false;
    243   }
    244 
    245   if (addr < start_ || max_size > real_size) {
    246     return false;
    247   }
    248   memcpy(dst, &data_[addr + offset_ - start_ + sizeof(start_)], size);
    249   return true;
    250 }
    251 
    252 MemoryRange::MemoryRange(Memory* memory, uint64_t begin, uint64_t end)
    253     : memory_(memory), begin_(begin), length_(end - begin) {
    254   CHECK(end > begin);
    255 }
    256 
    257 bool MemoryRange::Read(uint64_t addr, void* dst, size_t size) {
    258   uint64_t max_read;
    259   if (__builtin_add_overflow(addr, size, &max_read) || max_read > length_) {
    260     return false;
    261   }
    262   // The check above guarantees that addr + begin_ will not overflow.
    263   return memory_->Read(addr + begin_, dst, size);
    264 }
    265 
    266 }  // namespace unwindstack
    267