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