1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <dirent.h>
30 #include <fcntl.h>
31 #include <poll.h>
32 #include <pthread.h>
33 #include <stddef.h>
34 #include <sys/ucontext.h>
35 #include <syscall.h>
36 #include <unistd.h>
37
38 #include <atomic>
39 #include <memory>
40 #include <mutex>
41
42 #include <android-base/file.h>
43 #include <android-base/unique_fd.h>
44 #include <async_safe/log.h>
45 #include <bionic/reserved_signals.h>
46 #include <unwindstack/DexFiles.h>
47 #include <unwindstack/JitDebug.h>
48 #include <unwindstack/Maps.h>
49 #include <unwindstack/Memory.h>
50 #include <unwindstack/Regs.h>
51 #include <unwindstack/Unwinder.h>
52
53 #include "debuggerd/handler.h"
54 #include "handler/fallback.h"
55 #include "tombstoned/tombstoned.h"
56 #include "util.h"
57
58 #include "libdebuggerd/backtrace.h"
59 #include "libdebuggerd/tombstone.h"
60
61 using android::base::unique_fd;
62
63 extern "C" bool __linker_enable_fallback_allocator();
64 extern "C" void __linker_disable_fallback_allocator();
65
66 // This is incredibly sketchy to do inside of a signal handler, especially when libbacktrace
67 // uses the C++ standard library throughout, but this code runs in the linker, so we'll be using
68 // the linker's malloc instead of the libc one. Switch it out for a replacement, just in case.
69 //
70 // This isn't the default method of dumping because it can fail in cases such as address space
71 // exhaustion.
debuggerd_fallback_trace(int output_fd,ucontext_t * ucontext)72 static void debuggerd_fallback_trace(int output_fd, ucontext_t* ucontext) {
73 if (!__linker_enable_fallback_allocator()) {
74 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "fallback allocator already in use");
75 return;
76 }
77
78 {
79 std::unique_ptr<unwindstack::Regs> regs;
80
81 ThreadInfo thread;
82 thread.pid = getpid();
83 thread.tid = gettid();
84 thread.thread_name = get_thread_name(gettid());
85 thread.registers.reset(
86 unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
87
88 // TODO: Create this once and store it in a global?
89 unwindstack::UnwinderFromPid unwinder(kMaxFrames, getpid());
90 // Do not use the thread cache here because it will call pthread_key_create
91 // which doesn't work in linker code. See b/189803009.
92 // Use a normal cached object because the process is stopped, and there
93 // is no chance of data changing between reads.
94 auto process_memory = unwindstack::Memory::CreateProcessMemoryCached(getpid());
95 unwinder.SetProcessMemory(process_memory);
96 dump_backtrace_thread(output_fd, &unwinder, thread);
97 }
98 __linker_disable_fallback_allocator();
99 }
100
debuggerd_fallback_tombstone(int output_fd,int proto_fd,ucontext_t * ucontext,siginfo_t * siginfo,void * abort_message)101 static void debuggerd_fallback_tombstone(int output_fd, int proto_fd, ucontext_t* ucontext,
102 siginfo_t* siginfo, void* abort_message) {
103 if (!__linker_enable_fallback_allocator()) {
104 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "fallback allocator already in use");
105 return;
106 }
107
108 engrave_tombstone_ucontext(output_fd, proto_fd, reinterpret_cast<uintptr_t>(abort_message),
109 siginfo, ucontext);
110 __linker_disable_fallback_allocator();
111 }
112
iterate_siblings(bool (* callback)(pid_t,int),int output_fd)113 static void iterate_siblings(bool (*callback)(pid_t, int), int output_fd) {
114 pid_t current_tid = gettid();
115 char buf[BUFSIZ];
116 snprintf(buf, sizeof(buf), "/proc/%d/task", current_tid);
117 DIR* dir = opendir(buf);
118
119 if (!dir) {
120 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open %s: %s", buf, strerror(errno));
121 return;
122 }
123
124 struct dirent* ent;
125 while ((ent = readdir(dir))) {
126 char* end;
127 long tid = strtol(ent->d_name, &end, 10);
128 if (end == ent->d_name || *end != '\0') {
129 continue;
130 }
131
132 if (tid != current_tid) {
133 callback(tid, output_fd);
134 }
135 }
136 closedir(dir);
137 }
138
forward_output(int src_fd,int dst_fd,pid_t expected_tid)139 static bool forward_output(int src_fd, int dst_fd, pid_t expected_tid) {
140 // Make sure the thread actually got the signal.
141 struct pollfd pfd = {
142 .fd = src_fd, .events = POLLIN,
143 };
144
145 // Wait for up to a second for output to start flowing.
146 if (poll(&pfd, 1, 1000) != 1) {
147 return false;
148 }
149
150 pid_t tid;
151 if (TEMP_FAILURE_RETRY(read(src_fd, &tid, sizeof(tid))) != sizeof(tid)) {
152 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to read tid");
153 return false;
154 }
155
156 if (tid != expected_tid) {
157 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "received tid %d, expected %d", tid,
158 expected_tid);
159 return false;
160 }
161
162 while (true) {
163 char buf[512];
164 ssize_t rc = TEMP_FAILURE_RETRY(read(src_fd, buf, sizeof(buf)));
165 if (rc == 0) {
166 return true;
167 } else if (rc < 0) {
168 return false;
169 }
170
171 if (!android::base::WriteFully(dst_fd, buf, rc)) {
172 // We failed to write to tombstoned, but there's not much we can do.
173 // Keep reading from src_fd to keep things going.
174 continue;
175 }
176 }
177 }
178
179 struct __attribute__((__packed__)) packed_thread_output {
180 int32_t tid;
181 int32_t fd;
182 };
183
pack_thread_fd(pid_t tid,int fd)184 static uint64_t pack_thread_fd(pid_t tid, int fd) {
185 packed_thread_output packed = {.tid = tid, .fd = fd};
186 uint64_t result;
187 static_assert(sizeof(packed) == sizeof(result));
188 memcpy(&result, &packed, sizeof(packed));
189 return result;
190 }
191
unpack_thread_fd(uint64_t value)192 static std::pair<pid_t, int> unpack_thread_fd(uint64_t value) {
193 packed_thread_output result;
194 memcpy(&result, &value, sizeof(value));
195 return std::make_pair(result.tid, result.fd);
196 }
197
trace_handler(siginfo_t * info,ucontext_t * ucontext)198 static void trace_handler(siginfo_t* info, ucontext_t* ucontext) {
199 static std::atomic<uint64_t> trace_output(pack_thread_fd(-1, -1));
200
201 if (info->si_value.sival_ptr == kDebuggerdFallbackSivalPtrRequestDump) {
202 // Asked to dump by the original signal recipient.
203 uint64_t val = trace_output.load();
204 auto [tid, fd] = unpack_thread_fd(val);
205 if (tid != gettid()) {
206 // We received some other thread's info request?
207 async_safe_format_log(ANDROID_LOG_ERROR, "libc",
208 "thread %d received output fd for thread %d?", gettid(), tid);
209 return;
210 }
211
212 if (!trace_output.compare_exchange_strong(val, pack_thread_fd(-1, -1))) {
213 // Presumably, the timeout in forward_output expired, and the main thread moved on.
214 // If this happened, the main thread closed our fd for us, so just return.
215 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "cmpxchg for thread %d failed", gettid());
216 return;
217 }
218
219 // Write our tid to the output fd to let the main thread know that we're working.
220 if (TEMP_FAILURE_RETRY(write(fd, &tid, sizeof(tid))) == sizeof(tid)) {
221 debuggerd_fallback_trace(fd, ucontext);
222 } else {
223 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to write to output fd");
224 }
225
226 close(fd);
227 return;
228 }
229
230 // Only allow one thread to perform a trace at a time.
231 static pthread_mutex_t trace_mutex = PTHREAD_MUTEX_INITIALIZER;
232 int ret = pthread_mutex_trylock(&trace_mutex);
233 if (ret != 0) {
234 async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_try_lock failed: %s",
235 strerror(ret));
236 return;
237 }
238
239 // Fetch output fd from tombstoned.
240 unique_fd tombstone_socket, output_fd;
241 if (!tombstoned_connect(getpid(), &tombstone_socket, &output_fd, nullptr,
242 kDebuggerdNativeBacktrace)) {
243 async_safe_format_log(ANDROID_LOG_ERROR, "libc",
244 "missing crash_dump_fallback() in selinux policy?");
245 goto exit;
246 }
247
248 dump_backtrace_header(output_fd.get());
249
250 // Dump our own stack.
251 debuggerd_fallback_trace(output_fd.get(), ucontext);
252
253 // Send a signal to all of our siblings, asking them to dump their stack.
254 iterate_siblings(
255 [](pid_t tid, int output_fd) {
256 // Use a pipe, to be able to detect situations where the thread gracefully exits before
257 // receiving our signal.
258 unique_fd pipe_read, pipe_write;
259 if (!Pipe(&pipe_read, &pipe_write)) {
260 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create pipe: %s",
261 strerror(errno));
262 return false;
263 }
264
265 uint64_t expected = pack_thread_fd(-1, -1);
266 int sent_fd = pipe_write.release();
267 if (!trace_output.compare_exchange_strong(expected, pack_thread_fd(tid, sent_fd))) {
268 auto [tid, fd] = unpack_thread_fd(expected);
269 async_safe_format_log(ANDROID_LOG_ERROR, "libc",
270 "thread %d is already outputting to fd %d?", tid, fd);
271 close(sent_fd);
272 return false;
273 }
274
275 siginfo_t siginfo = {};
276 siginfo.si_code = SI_QUEUE;
277 siginfo.si_value.sival_ptr = kDebuggerdFallbackSivalPtrRequestDump;
278 siginfo.si_pid = getpid();
279 siginfo.si_uid = getuid();
280
281 if (syscall(__NR_rt_tgsigqueueinfo, getpid(), tid, BIONIC_SIGNAL_DEBUGGER, &siginfo) != 0) {
282 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to send trace signal to %d: %s",
283 tid, strerror(errno));
284 return false;
285 }
286
287 bool success = forward_output(pipe_read.get(), output_fd, tid);
288 if (!success) {
289 async_safe_format_log(ANDROID_LOG_ERROR, "libc",
290 "timeout expired while waiting for thread %d to dump", tid);
291 }
292
293 // Regardless of whether the poll succeeds, check to see if the thread took fd ownership.
294 uint64_t post_wait = trace_output.exchange(pack_thread_fd(-1, -1));
295 if (post_wait != pack_thread_fd(-1, -1)) {
296 auto [tid, fd] = unpack_thread_fd(post_wait);
297 if (fd != -1) {
298 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "closing fd %d for thread %d", fd, tid);
299 close(fd);
300 }
301 }
302
303 return true;
304 },
305 output_fd.get());
306
307 dump_backtrace_footer(output_fd.get());
308 tombstoned_notify_completion(tombstone_socket.get());
309
310 exit:
311 pthread_mutex_unlock(&trace_mutex);
312 }
313
crash_handler(siginfo_t * info,ucontext_t * ucontext,void * abort_message)314 static void crash_handler(siginfo_t* info, ucontext_t* ucontext, void* abort_message) {
315 // Only allow one thread to handle a crash at a time (this can happen multiple times without
316 // exit, since tombstones can be requested without a real crash happening.)
317 static std::recursive_mutex crash_mutex;
318 static int lock_count;
319
320 crash_mutex.lock();
321 if (lock_count++ > 0) {
322 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "recursed signal handler call, aborting");
323 signal(SIGABRT, SIG_DFL);
324 raise(SIGABRT);
325 sigset_t sigset;
326 sigemptyset(&sigset);
327 sigaddset(&sigset, SIGABRT);
328 sigprocmask(SIG_UNBLOCK, &sigset, nullptr);
329
330 // Just in case...
331 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "abort didn't exit, exiting");
332 _exit(1);
333 }
334
335 unique_fd tombstone_socket, output_fd, proto_fd;
336 bool tombstoned_connected = tombstoned_connect(getpid(), &tombstone_socket, &output_fd, &proto_fd,
337 kDebuggerdTombstoneProto);
338 debuggerd_fallback_tombstone(output_fd.get(), proto_fd.get(), ucontext, info, abort_message);
339 if (tombstoned_connected) {
340 tombstoned_notify_completion(tombstone_socket.get());
341 }
342
343 --lock_count;
344 crash_mutex.unlock();
345 }
346
debuggerd_fallback_handler(siginfo_t * info,ucontext_t * ucontext,void * abort_message)347 extern "C" void debuggerd_fallback_handler(siginfo_t* info, ucontext_t* ucontext,
348 void* abort_message) {
349 if (info->si_signo == BIONIC_SIGNAL_DEBUGGER && info->si_value.sival_ptr != nullptr) {
350 return trace_handler(info, ucontext);
351 } else {
352 return crash_handler(info, ucontext, abort_message);
353 }
354 }
355