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 static size_t ProcessVmRead(pid_t pid, uint64_t remote_src, void* dst, size_t len) { 38 39 // Split up the remote read across page boundaries. 40 // From the manpage: 41 // A partial read/write may result if one of the remote_iov elements points to an invalid 42 // memory region in the remote process. 43 // 44 // Partial transfers apply at the granularity of iovec elements. These system calls won't 45 // perform a partial transfer that splits a single iovec element. 46 constexpr size_t kMaxIovecs = 64; 47 struct iovec src_iovs[kMaxIovecs]; 48 49 uint64_t cur = remote_src; 50 size_t total_read = 0; 51 while (len > 0) { 52 struct iovec dst_iov = { 53 .iov_base = &reinterpret_cast<uint8_t*>(dst)[total_read], .iov_len = len, 54 }; 55 56 size_t iovecs_used = 0; 57 while (len > 0) { 58 if (iovecs_used == kMaxIovecs) { 59 break; 60 } 61 62 // struct iovec uses void* for iov_base. 63 if (cur >= UINTPTR_MAX) { 64 errno = EFAULT; 65 return total_read; 66 } 67 68 src_iovs[iovecs_used].iov_base = reinterpret_cast<void*>(cur); 69 70 uintptr_t misalignment = cur & (getpagesize() - 1); 71 size_t iov_len = getpagesize() - misalignment; 72 iov_len = std::min(iov_len, len); 73 74 len -= iov_len; 75 if (__builtin_add_overflow(cur, iov_len, &cur)) { 76 errno = EFAULT; 77 return total_read; 78 } 79 80 src_iovs[iovecs_used].iov_len = iov_len; 81 ++iovecs_used; 82 } 83 84 ssize_t rc = process_vm_readv(pid, &dst_iov, 1, src_iovs, iovecs_used, 0); 85 if (rc == -1) { 86 return total_read; 87 } 88 total_read += rc; 89 } 90 return total_read; 91 } 92 93 static bool PtraceReadLong(pid_t pid, uint64_t addr, long* value) { 94 // ptrace() returns -1 and sets errno when the operation fails. 95 // To disambiguate -1 from a valid result, we clear errno beforehand. 96 errno = 0; 97 *value = ptrace(PTRACE_PEEKTEXT, pid, reinterpret_cast<void*>(addr), nullptr); 98 if (*value == -1 && errno) { 99 return false; 100 } 101 return true; 102 } 103 104 static size_t PtraceRead(pid_t pid, uint64_t addr, void* dst, size_t bytes) { 105 // Make sure that there is no overflow. 106 uint64_t max_size; 107 if (__builtin_add_overflow(addr, bytes, &max_size)) { 108 return 0; 109 } 110 111 size_t bytes_read = 0; 112 long data; 113 size_t align_bytes = addr & (sizeof(long) - 1); 114 if (align_bytes != 0) { 115 if (!PtraceReadLong(pid, addr & ~(sizeof(long) - 1), &data)) { 116 return 0; 117 } 118 size_t copy_bytes = std::min(sizeof(long) - align_bytes, bytes); 119 memcpy(dst, reinterpret_cast<uint8_t*>(&data) + align_bytes, copy_bytes); 120 addr += copy_bytes; 121 dst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(dst) + copy_bytes); 122 bytes -= copy_bytes; 123 bytes_read += copy_bytes; 124 } 125 126 for (size_t i = 0; i < bytes / sizeof(long); i++) { 127 if (!PtraceReadLong(pid, addr, &data)) { 128 return bytes_read; 129 } 130 memcpy(dst, &data, sizeof(long)); 131 dst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(dst) + sizeof(long)); 132 addr += sizeof(long); 133 bytes_read += sizeof(long); 134 } 135 136 size_t left_over = bytes & (sizeof(long) - 1); 137 if (left_over) { 138 if (!PtraceReadLong(pid, addr, &data)) { 139 return bytes_read; 140 } 141 memcpy(dst, &data, left_over); 142 bytes_read += left_over; 143 } 144 return bytes_read; 145 } 146 147 bool Memory::ReadFully(uint64_t addr, void* dst, size_t size) { 148 size_t rc = Read(addr, dst, size); 149 return rc == size; 150 } 151 152 bool Memory::ReadString(uint64_t addr, std::string* string, uint64_t max_read) { 153 string->clear(); 154 uint64_t bytes_read = 0; 155 while (bytes_read < max_read) { 156 uint8_t value; 157 if (!ReadFully(addr, &value, sizeof(value))) { 158 return false; 159 } 160 if (value == '\0') { 161 return true; 162 } 163 string->push_back(value); 164 addr++; 165 bytes_read++; 166 } 167 return false; 168 } 169 170 std::shared_ptr<Memory> Memory::CreateProcessMemory(pid_t pid) { 171 if (pid == getpid()) { 172 return std::shared_ptr<Memory>(new MemoryLocal()); 173 } 174 return std::shared_ptr<Memory>(new MemoryRemote(pid)); 175 } 176 177 size_t MemoryBuffer::Read(uint64_t addr, void* dst, size_t size) { 178 if (addr >= raw_.size()) { 179 return 0; 180 } 181 182 size_t bytes_left = raw_.size() - static_cast<size_t>(addr); 183 const unsigned char* actual_base = static_cast<const unsigned char*>(raw_.data()) + addr; 184 size_t actual_len = std::min(bytes_left, size); 185 186 memcpy(dst, actual_base, actual_len); 187 return actual_len; 188 } 189 190 uint8_t* MemoryBuffer::GetPtr(size_t offset) { 191 if (offset < raw_.size()) { 192 return &raw_[offset]; 193 } 194 return nullptr; 195 } 196 197 MemoryFileAtOffset::~MemoryFileAtOffset() { 198 Clear(); 199 } 200 201 void MemoryFileAtOffset::Clear() { 202 if (data_) { 203 munmap(&data_[-offset_], size_ + offset_); 204 data_ = nullptr; 205 } 206 } 207 208 bool MemoryFileAtOffset::Init(const std::string& file, uint64_t offset, uint64_t size) { 209 // Clear out any previous data if it exists. 210 Clear(); 211 212 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(file.c_str(), O_RDONLY | O_CLOEXEC))); 213 if (fd == -1) { 214 return false; 215 } 216 struct stat buf; 217 if (fstat(fd, &buf) == -1) { 218 return false; 219 } 220 if (offset >= static_cast<uint64_t>(buf.st_size)) { 221 return false; 222 } 223 224 offset_ = offset & (getpagesize() - 1); 225 uint64_t aligned_offset = offset & ~(getpagesize() - 1); 226 if (aligned_offset > static_cast<uint64_t>(buf.st_size) || 227 offset > static_cast<uint64_t>(buf.st_size)) { 228 return false; 229 } 230 231 size_ = buf.st_size - aligned_offset; 232 uint64_t max_size; 233 if (!__builtin_add_overflow(size, offset_, &max_size) && max_size < size_) { 234 // Truncate the mapped size. 235 size_ = max_size; 236 } 237 void* map = mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, fd, aligned_offset); 238 if (map == MAP_FAILED) { 239 return false; 240 } 241 242 data_ = &reinterpret_cast<uint8_t*>(map)[offset_]; 243 size_ -= offset_; 244 245 return true; 246 } 247 248 size_t MemoryFileAtOffset::Read(uint64_t addr, void* dst, size_t size) { 249 if (addr >= size_) { 250 return 0; 251 } 252 253 size_t bytes_left = size_ - static_cast<size_t>(addr); 254 const unsigned char* actual_base = static_cast<const unsigned char*>(data_) + addr; 255 size_t actual_len = std::min(bytes_left, size); 256 257 memcpy(dst, actual_base, actual_len); 258 return actual_len; 259 } 260 261 size_t MemoryRemote::Read(uint64_t addr, void* dst, size_t size) { 262 #if !defined(__LP64__) 263 // Cannot read an address greater than 32 bits in a 32 bit context. 264 if (addr > UINT32_MAX) { 265 return 0; 266 } 267 #endif 268 269 size_t (*read_func)(pid_t, uint64_t, void*, size_t) = 270 reinterpret_cast<size_t (*)(pid_t, uint64_t, void*, size_t)>(read_redirect_func_.load()); 271 if (read_func != nullptr) { 272 return read_func(pid_, addr, dst, size); 273 } else { 274 // Prefer process_vm_read, try it first. If it doesn't work, use the 275 // ptrace function. If at least one of them returns at least some data, 276 // set that as the permanent function to use. 277 // This assumes that if process_vm_read works once, it will continue 278 // to work. 279 size_t bytes = ProcessVmRead(pid_, addr, dst, size); 280 if (bytes > 0) { 281 read_redirect_func_ = reinterpret_cast<uintptr_t>(ProcessVmRead); 282 return bytes; 283 } 284 bytes = PtraceRead(pid_, addr, dst, size); 285 if (bytes > 0) { 286 read_redirect_func_ = reinterpret_cast<uintptr_t>(PtraceRead); 287 } 288 return bytes; 289 } 290 } 291 292 size_t MemoryLocal::Read(uint64_t addr, void* dst, size_t size) { 293 return ProcessVmRead(getpid(), addr, dst, size); 294 } 295 296 MemoryRange::MemoryRange(const std::shared_ptr<Memory>& memory, uint64_t begin, uint64_t length, 297 uint64_t offset) 298 : memory_(memory), begin_(begin), length_(length), offset_(offset) {} 299 300 size_t MemoryRange::Read(uint64_t addr, void* dst, size_t size) { 301 if (addr < offset_) { 302 return 0; 303 } 304 305 uint64_t read_offset = addr - offset_; 306 if (read_offset >= length_) { 307 return 0; 308 } 309 310 uint64_t read_length = std::min(static_cast<uint64_t>(size), length_ - read_offset); 311 uint64_t read_addr; 312 if (__builtin_add_overflow(read_offset, begin_, &read_addr)) { 313 return 0; 314 } 315 316 return memory_->Read(read_addr, dst, read_length); 317 } 318 319 bool MemoryOffline::Init(const std::string& file, uint64_t offset) { 320 auto memory_file = std::make_shared<MemoryFileAtOffset>(); 321 if (!memory_file->Init(file, offset)) { 322 return false; 323 } 324 325 // The first uint64_t value is the start of memory. 326 uint64_t start; 327 if (!memory_file->ReadFully(0, &start, sizeof(start))) { 328 return false; 329 } 330 331 uint64_t size = memory_file->Size(); 332 if (__builtin_sub_overflow(size, sizeof(start), &size)) { 333 return false; 334 } 335 336 memory_ = std::make_unique<MemoryRange>(memory_file, sizeof(start), size, start); 337 return true; 338 } 339 340 size_t MemoryOffline::Read(uint64_t addr, void* dst, size_t size) { 341 if (!memory_) { 342 return 0; 343 } 344 345 return memory_->Read(addr, dst, size); 346 } 347 348 MemoryOfflineBuffer::MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end) 349 : data_(data), start_(start), end_(end) {} 350 351 void MemoryOfflineBuffer::Reset(const uint8_t* data, uint64_t start, uint64_t end) { 352 data_ = data; 353 start_ = start; 354 end_ = end; 355 } 356 357 size_t MemoryOfflineBuffer::Read(uint64_t addr, void* dst, size_t size) { 358 if (addr < start_ || addr >= end_) { 359 return 0; 360 } 361 362 size_t read_length = std::min(size, static_cast<size_t>(end_ - addr)); 363 memcpy(dst, &data_[addr - start_], read_length); 364 return read_length; 365 } 366 367 MemoryOfflineParts::~MemoryOfflineParts() { 368 for (auto memory : memories_) { 369 delete memory; 370 } 371 } 372 373 size_t MemoryOfflineParts::Read(uint64_t addr, void* dst, size_t size) { 374 if (memories_.empty()) { 375 return 0; 376 } 377 378 // Do a read on each memory object, no support for reading across the 379 // different memory objects. 380 for (MemoryOffline* memory : memories_) { 381 size_t bytes = memory->Read(addr, dst, size); 382 if (bytes != 0) { 383 return bytes; 384 } 385 } 386 return 0; 387 } 388 389 } // namespace unwindstack 390