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 <signal.h> 19 #include <stdint.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <sys/mman.h> 23 #include <sys/ptrace.h> 24 #include <sys/types.h> 25 #include <unistd.h> 26 27 #include <vector> 28 29 #include <android-base/test_utils.h> 30 #include <android-base/file.h> 31 #include <gtest/gtest.h> 32 33 #include <unwindstack/Memory.h> 34 35 #include "MemoryFake.h" 36 #include "TestUtils.h" 37 38 namespace unwindstack { 39 40 class MemoryRemoteTest : public ::testing::Test { 41 protected: 42 static bool Attach(pid_t pid) { 43 if (ptrace(PTRACE_ATTACH, pid, 0, 0) == -1) { 44 return false; 45 } 46 47 return TestQuiescePid(pid); 48 } 49 50 static bool Detach(pid_t pid) { 51 return ptrace(PTRACE_DETACH, pid, 0, 0) == 0; 52 } 53 54 static constexpr size_t NS_PER_SEC = 1000000000ULL; 55 }; 56 57 TEST_F(MemoryRemoteTest, read) { 58 std::vector<uint8_t> src(1024); 59 memset(src.data(), 0x4c, 1024); 60 61 pid_t pid; 62 if ((pid = fork()) == 0) { 63 while (true); 64 exit(1); 65 } 66 ASSERT_LT(0, pid); 67 TestScopedPidReaper reap(pid); 68 69 ASSERT_TRUE(Attach(pid)); 70 71 MemoryRemote remote(pid); 72 73 std::vector<uint8_t> dst(1024); 74 ASSERT_TRUE(remote.ReadFully(reinterpret_cast<uint64_t>(src.data()), dst.data(), 1024)); 75 for (size_t i = 0; i < 1024; i++) { 76 ASSERT_EQ(0x4cU, dst[i]) << "Failed at byte " << i; 77 } 78 79 ASSERT_TRUE(Detach(pid)); 80 } 81 82 TEST_F(MemoryRemoteTest, read_large) { 83 static constexpr size_t kTotalPages = 245; 84 std::vector<uint8_t> src(kTotalPages * getpagesize()); 85 for (size_t i = 0; i < kTotalPages; i++) { 86 memset(&src[i * getpagesize()], i, getpagesize()); 87 } 88 89 pid_t pid; 90 if ((pid = fork()) == 0) { 91 while (true) 92 ; 93 exit(1); 94 } 95 ASSERT_LT(0, pid); 96 TestScopedPidReaper reap(pid); 97 98 ASSERT_TRUE(Attach(pid)); 99 100 MemoryRemote remote(pid); 101 102 std::vector<uint8_t> dst(kTotalPages * getpagesize()); 103 ASSERT_TRUE(remote.ReadFully(reinterpret_cast<uint64_t>(src.data()), dst.data(), src.size())); 104 for (size_t i = 0; i < kTotalPages * getpagesize(); i++) { 105 ASSERT_EQ(i / getpagesize(), dst[i]) << "Failed at byte " << i; 106 } 107 108 ASSERT_TRUE(Detach(pid)); 109 } 110 111 TEST_F(MemoryRemoteTest, read_partial) { 112 char* mapping = static_cast<char*>( 113 mmap(nullptr, 4 * getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); 114 ASSERT_NE(MAP_FAILED, mapping); 115 memset(mapping, 0x4c, 4 * getpagesize()); 116 ASSERT_EQ(0, mprotect(mapping + getpagesize(), getpagesize(), PROT_NONE)); 117 ASSERT_EQ(0, munmap(mapping + 3 * getpagesize(), getpagesize())); 118 119 pid_t pid; 120 if ((pid = fork()) == 0) { 121 while (true) 122 ; 123 exit(1); 124 } 125 ASSERT_LT(0, pid); 126 TestScopedPidReaper reap(pid); 127 128 // Unmap from our process. 129 ASSERT_EQ(0, munmap(mapping, 3 * getpagesize())); 130 131 ASSERT_TRUE(Attach(pid)); 132 133 MemoryRemote remote(pid); 134 135 std::vector<uint8_t> dst(4096); 136 size_t bytes = 137 remote.Read(reinterpret_cast<uint64_t>(mapping + getpagesize() - 1024), dst.data(), 4096); 138 // Some read methods can read PROT_NONE maps, allow that. 139 ASSERT_LE(1024U, bytes); 140 for (size_t i = 0; i < bytes; i++) { 141 ASSERT_EQ(0x4cU, dst[i]) << "Failed at byte " << i; 142 } 143 144 // Now verify that reading stops at the end of a map. 145 bytes = 146 remote.Read(reinterpret_cast<uint64_t>(mapping + 3 * getpagesize() - 1024), dst.data(), 4096); 147 ASSERT_EQ(1024U, bytes); 148 for (size_t i = 0; i < bytes; i++) { 149 ASSERT_EQ(0x4cU, dst[i]) << "Failed at byte " << i; 150 } 151 152 ASSERT_TRUE(Detach(pid)); 153 } 154 155 TEST_F(MemoryRemoteTest, read_fail) { 156 int pagesize = getpagesize(); 157 void* src = mmap(nullptr, pagesize * 2, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1, 0); 158 memset(src, 0x4c, pagesize * 2); 159 ASSERT_NE(MAP_FAILED, src); 160 // Put a hole right after the first page. 161 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(src) + pagesize), 162 pagesize)); 163 164 pid_t pid; 165 if ((pid = fork()) == 0) { 166 while (true); 167 exit(1); 168 } 169 ASSERT_LT(0, pid); 170 TestScopedPidReaper reap(pid); 171 172 ASSERT_TRUE(Attach(pid)); 173 174 MemoryRemote remote(pid); 175 176 std::vector<uint8_t> dst(pagesize); 177 ASSERT_TRUE(remote.ReadFully(reinterpret_cast<uint64_t>(src), dst.data(), pagesize)); 178 for (size_t i = 0; i < 1024; i++) { 179 ASSERT_EQ(0x4cU, dst[i]) << "Failed at byte " << i; 180 } 181 182 ASSERT_FALSE(remote.ReadFully(reinterpret_cast<uint64_t>(src) + pagesize, dst.data(), 1)); 183 ASSERT_TRUE(remote.ReadFully(reinterpret_cast<uint64_t>(src) + pagesize - 1, dst.data(), 1)); 184 ASSERT_FALSE(remote.ReadFully(reinterpret_cast<uint64_t>(src) + pagesize - 4, dst.data(), 8)); 185 186 // Check overflow condition is caught properly. 187 ASSERT_FALSE(remote.ReadFully(UINT64_MAX - 100, dst.data(), 200)); 188 189 ASSERT_EQ(0, munmap(src, pagesize)); 190 191 ASSERT_TRUE(Detach(pid)); 192 } 193 194 TEST_F(MemoryRemoteTest, read_overflow) { 195 pid_t pid; 196 if ((pid = fork()) == 0) { 197 while (true) 198 ; 199 exit(1); 200 } 201 ASSERT_LT(0, pid); 202 TestScopedPidReaper reap(pid); 203 204 ASSERT_TRUE(Attach(pid)); 205 206 MemoryRemote remote(pid); 207 208 // Check overflow condition is caught properly. 209 std::vector<uint8_t> dst(200); 210 ASSERT_FALSE(remote.ReadFully(UINT64_MAX - 100, dst.data(), 200)); 211 212 ASSERT_TRUE(Detach(pid)); 213 } 214 215 TEST_F(MemoryRemoteTest, read_illegal) { 216 pid_t pid; 217 if ((pid = fork()) == 0) { 218 while (true); 219 exit(1); 220 } 221 ASSERT_LT(0, pid); 222 TestScopedPidReaper reap(pid); 223 224 ASSERT_TRUE(Attach(pid)); 225 226 MemoryRemote remote(pid); 227 228 std::vector<uint8_t> dst(100); 229 ASSERT_FALSE(remote.ReadFully(0, dst.data(), 1)); 230 ASSERT_FALSE(remote.ReadFully(0, dst.data(), 100)); 231 232 ASSERT_TRUE(Detach(pid)); 233 } 234 235 TEST_F(MemoryRemoteTest, read_mprotect_hole) { 236 size_t page_size = getpagesize(); 237 void* mapping = 238 mmap(nullptr, 3 * getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 239 ASSERT_NE(MAP_FAILED, mapping); 240 memset(mapping, 0xFF, 3 * page_size); 241 ASSERT_EQ(0, mprotect(static_cast<char*>(mapping) + page_size, page_size, PROT_NONE)); 242 243 pid_t pid; 244 if ((pid = fork()) == 0) { 245 while (true); 246 exit(1); 247 } 248 ASSERT_LT(0, pid); 249 TestScopedPidReaper reap(pid); 250 251 ASSERT_EQ(0, munmap(mapping, 3 * page_size)); 252 253 ASSERT_TRUE(Attach(pid)); 254 255 MemoryRemote remote(pid); 256 std::vector<uint8_t> dst(getpagesize() * 4, 0xCC); 257 size_t read_size = remote.Read(reinterpret_cast<uint64_t>(mapping), dst.data(), page_size * 3); 258 // Some read methods can read PROT_NONE maps, allow that. 259 ASSERT_LE(page_size, read_size); 260 for (size_t i = 0; i < read_size; ++i) { 261 ASSERT_EQ(0xFF, dst[i]); 262 } 263 for (size_t i = read_size; i < dst.size(); ++i) { 264 ASSERT_EQ(0xCC, dst[i]); 265 } 266 } 267 268 TEST_F(MemoryRemoteTest, read_munmap_hole) { 269 size_t page_size = getpagesize(); 270 void* mapping = 271 mmap(nullptr, 3 * getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 272 ASSERT_NE(MAP_FAILED, mapping); 273 memset(mapping, 0xFF, 3 * page_size); 274 ASSERT_EQ(0, munmap(static_cast<char*>(mapping) + page_size, page_size)); 275 276 pid_t pid; 277 if ((pid = fork()) == 0) { 278 while (true) 279 ; 280 exit(1); 281 } 282 ASSERT_LT(0, pid); 283 TestScopedPidReaper reap(pid); 284 285 ASSERT_EQ(0, munmap(mapping, page_size)); 286 ASSERT_EQ(0, munmap(static_cast<char*>(mapping) + 2 * page_size, page_size)); 287 288 ASSERT_TRUE(Attach(pid)); 289 290 MemoryRemote remote(pid); 291 std::vector<uint8_t> dst(getpagesize() * 4, 0xCC); 292 size_t read_size = remote.Read(reinterpret_cast<uint64_t>(mapping), dst.data(), page_size * 3); 293 ASSERT_EQ(page_size, read_size); 294 for (size_t i = 0; i < read_size; ++i) { 295 ASSERT_EQ(0xFF, dst[i]); 296 } 297 for (size_t i = read_size; i < dst.size(); ++i) { 298 ASSERT_EQ(0xCC, dst[i]); 299 } 300 } 301 302 // Verify that the memory remote object chooses a memory read function 303 // properly. Either process_vm_readv or ptrace. 304 TEST_F(MemoryRemoteTest, read_choose_correctly) { 305 size_t page_size = getpagesize(); 306 void* mapping = 307 mmap(nullptr, 2 * getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 308 ASSERT_NE(MAP_FAILED, mapping); 309 memset(mapping, 0xFC, 2 * page_size); 310 ASSERT_EQ(0, mprotect(static_cast<char*>(mapping), page_size, PROT_NONE)); 311 312 pid_t pid; 313 if ((pid = fork()) == 0) { 314 while (true) 315 ; 316 exit(1); 317 } 318 ASSERT_LT(0, pid); 319 TestScopedPidReaper reap(pid); 320 321 ASSERT_EQ(0, munmap(mapping, 2 * page_size)); 322 323 ASSERT_TRUE(Attach(pid)); 324 325 // We know that process_vm_readv of a mprotect'd PROT_NONE region will fail. 326 // Read from the PROT_NONE area first to force the choice of ptrace. 327 MemoryRemote remote_ptrace(pid); 328 uint32_t value; 329 size_t bytes = remote_ptrace.Read(reinterpret_cast<uint64_t>(mapping), &value, sizeof(value)); 330 ASSERT_EQ(sizeof(value), bytes); 331 ASSERT_EQ(0xfcfcfcfcU, value); 332 bytes = remote_ptrace.Read(reinterpret_cast<uint64_t>(mapping) + page_size, &value, sizeof(value)); 333 ASSERT_EQ(sizeof(value), bytes); 334 ASSERT_EQ(0xfcfcfcfcU, value); 335 bytes = remote_ptrace.Read(reinterpret_cast<uint64_t>(mapping), &value, sizeof(value)); 336 ASSERT_EQ(sizeof(value), bytes); 337 ASSERT_EQ(0xfcfcfcfcU, value); 338 339 // Now verify that choosing process_vm_readv results in failing reads of 340 // the PROT_NONE part of the map. Read from a valid map first which 341 // should prefer process_vm_readv, and keep that as the read function. 342 MemoryRemote remote_readv(pid); 343 bytes = remote_readv.Read(reinterpret_cast<uint64_t>(mapping) + page_size, &value, sizeof(value)); 344 ASSERT_EQ(sizeof(value), bytes); 345 ASSERT_EQ(0xfcfcfcfcU, value); 346 bytes = remote_readv.Read(reinterpret_cast<uint64_t>(mapping), &value, sizeof(value)); 347 ASSERT_EQ(0U, bytes); 348 bytes = remote_readv.Read(reinterpret_cast<uint64_t>(mapping) + page_size, &value, sizeof(value)); 349 ASSERT_EQ(sizeof(value), bytes); 350 ASSERT_EQ(0xfcfcfcfcU, value); 351 } 352 353 } // namespace unwindstack 354