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