Home | History | Annotate | Download | only in debuggerd
      1 /*
      2  * Copyright 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 <arpa/inet.h>
     18 #include <dirent.h>
     19 #include <fcntl.h>
     20 #include <stdlib.h>
     21 #include <sys/capability.h>
     22 #include <sys/prctl.h>
     23 #include <sys/ptrace.h>
     24 #include <sys/types.h>
     25 #include <sys/un.h>
     26 #include <syscall.h>
     27 #include <unistd.h>
     28 
     29 #include <limits>
     30 #include <map>
     31 #include <memory>
     32 #include <set>
     33 #include <vector>
     34 
     35 #include <android-base/file.h>
     36 #include <android-base/logging.h>
     37 #include <android-base/parseint.h>
     38 #include <android-base/properties.h>
     39 #include <android-base/stringprintf.h>
     40 #include <android-base/strings.h>
     41 #include <android-base/unique_fd.h>
     42 #include <cutils/sockets.h>
     43 #include <log/log.h>
     44 #include <private/android_filesystem_config.h>
     45 #include <procinfo/process.h>
     46 
     47 #define ATRACE_TAG ATRACE_TAG_BIONIC
     48 #include <utils/Trace.h>
     49 
     50 #include "backtrace.h"
     51 #include "tombstone.h"
     52 #include "utility.h"
     53 
     54 #include "debuggerd/handler.h"
     55 #include "protocol.h"
     56 #include "tombstoned/tombstoned.h"
     57 #include "util.h"
     58 
     59 using android::base::unique_fd;
     60 using android::base::ReadFileToString;
     61 using android::base::StringPrintf;
     62 using android::base::Trim;
     63 
     64 static std::string get_process_name(pid_t pid) {
     65   std::string result = "<unknown>";
     66   ReadFileToString(StringPrintf("/proc/%d/cmdline", pid), &result);
     67   return result;
     68 }
     69 
     70 static std::string get_thread_name(pid_t tid) {
     71   std::string result = "<unknown>";
     72   ReadFileToString(StringPrintf("/proc/%d/comm", tid), &result);
     73   return Trim(result);
     74 }
     75 
     76 static bool pid_contains_tid(int pid_proc_fd, pid_t tid) {
     77   struct stat st;
     78   std::string task_path = StringPrintf("task/%d", tid);
     79   return fstatat(pid_proc_fd, task_path.c_str(), &st, 0) == 0;
     80 }
     81 
     82 // Attach to a thread, and verify that it's still a member of the given process
     83 static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error) {
     84   if (ptrace(PTRACE_SEIZE, tid, 0, 0) != 0) {
     85     *error = StringPrintf("failed to attach to thread %d: %s", tid, strerror(errno));
     86     return false;
     87   }
     88 
     89   // Make sure that the task we attached to is actually part of the pid we're dumping.
     90   if (!pid_contains_tid(pid_proc_fd, tid)) {
     91     if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
     92       PLOG(FATAL) << "failed to detach from thread " << tid;
     93     }
     94     *error = StringPrintf("thread %d is not in process", tid);
     95     return false;
     96   }
     97 
     98   // Put the task into ptrace-stop state.
     99   if (ptrace(PTRACE_INTERRUPT, tid, 0, 0) != 0) {
    100     PLOG(FATAL) << "failed to interrupt thread " << tid;
    101   }
    102 
    103   return true;
    104 }
    105 
    106 static bool activity_manager_notify(pid_t pid, int signal, const std::string& amfd_data) {
    107   ATRACE_CALL();
    108   android::base::unique_fd amfd(socket_local_client(
    109       "/data/system/ndebugsocket", ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM));
    110   if (amfd.get() == -1) {
    111     PLOG(ERROR) << "unable to connect to activity manager";
    112     return false;
    113   }
    114 
    115   struct timeval tv = {
    116     .tv_sec = 1,
    117     .tv_usec = 0,
    118   };
    119   if (setsockopt(amfd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
    120     PLOG(ERROR) << "failed to set send timeout on activity manager socket";
    121     return false;
    122   }
    123   tv.tv_sec = 3;  // 3 seconds on handshake read
    124   if (setsockopt(amfd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
    125     PLOG(ERROR) << "failed to set receive timeout on activity manager socket";
    126     return false;
    127   }
    128 
    129   // Activity Manager protocol: binary 32-bit network-byte-order ints for the
    130   // pid and signal number, followed by the raw text of the dump, culminating
    131   // in a zero byte that marks end-of-data.
    132   uint32_t datum = htonl(pid);
    133   if (!android::base::WriteFully(amfd, &datum, 4)) {
    134     PLOG(ERROR) << "AM pid write failed";
    135     return false;
    136   }
    137   datum = htonl(signal);
    138   if (!android::base::WriteFully(amfd, &datum, 4)) {
    139     PLOG(ERROR) << "AM signal write failed";
    140     return false;
    141   }
    142   if (!android::base::WriteFully(amfd, amfd_data.c_str(), amfd_data.size() + 1)) {
    143     PLOG(ERROR) << "AM data write failed";
    144     return false;
    145   }
    146 
    147   // 3 sec timeout reading the ack; we're fine if the read fails.
    148   char ack;
    149   android::base::ReadFully(amfd, &ack, 1);
    150   return true;
    151 }
    152 
    153 static void signal_handler(int) {
    154   // We can't log easily, because the heap might be corrupt.
    155   // Just die and let the surrounding log context explain things.
    156   _exit(1);
    157 }
    158 
    159 static void abort_handler(pid_t target, const bool tombstoned_connected,
    160                           unique_fd& tombstoned_socket, unique_fd& output_fd,
    161                           const char* abort_msg) {
    162   // If we abort before we get an output fd, contact tombstoned to let any
    163   // potential listeners know that we failed.
    164   if (!tombstoned_connected) {
    165     if (!tombstoned_connect(target, &tombstoned_socket, &output_fd, kDebuggerdAnyIntercept)) {
    166       // We failed to connect, not much we can do.
    167       LOG(ERROR) << "failed to connected to tombstoned to report failure";
    168       _exit(1);
    169     }
    170   }
    171 
    172   dprintf(output_fd.get(), "crash_dump failed to dump process");
    173   if (target != 1) {
    174     dprintf(output_fd.get(), " %d: %s\n", target, abort_msg);
    175   } else {
    176     dprintf(output_fd.get(), ": %s\n", abort_msg);
    177   }
    178 
    179   _exit(1);
    180 }
    181 
    182 static void drop_capabilities() {
    183   ATRACE_CALL();
    184   __user_cap_header_struct capheader;
    185   memset(&capheader, 0, sizeof(capheader));
    186   capheader.version = _LINUX_CAPABILITY_VERSION_3;
    187   capheader.pid = 0;
    188 
    189   __user_cap_data_struct capdata[2];
    190   memset(&capdata, 0, sizeof(capdata));
    191 
    192   if (capset(&capheader, &capdata[0]) == -1) {
    193     PLOG(FATAL) << "failed to drop capabilities";
    194   }
    195 
    196   if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) {
    197     PLOG(FATAL) << "failed to set PR_SET_NO_NEW_PRIVS";
    198   }
    199 }
    200 
    201 int main(int argc, char** argv) {
    202   atrace_begin(ATRACE_TAG, "before reparent");
    203 
    204   pid_t target = getppid();
    205   bool tombstoned_connected = false;
    206   unique_fd tombstoned_socket;
    207   unique_fd output_fd;
    208 
    209   android::base::InitLogging(argv);
    210   android::base::SetAborter([&](const char* abort_msg) {
    211     abort_handler(target, tombstoned_connected, tombstoned_socket, output_fd, abort_msg);
    212   });
    213 
    214   // Don't try to dump ourselves.
    215   struct sigaction action = {};
    216   action.sa_handler = signal_handler;
    217   debuggerd_register_handlers(&action);
    218 
    219   sigset_t mask;
    220   sigemptyset(&mask);
    221   if (sigprocmask(SIG_SETMASK, &mask, nullptr) != 0) {
    222     PLOG(FATAL) << "failed to set signal mask";
    223   }
    224 
    225   if (argc != 4) {
    226     LOG(FATAL) << "Wrong number of args: " << argc << " (expected 4)";
    227   }
    228 
    229   pid_t main_tid;
    230   pid_t pseudothread_tid;
    231   int dump_type;
    232 
    233   if (!android::base::ParseInt(argv[1], &main_tid, 1, std::numeric_limits<pid_t>::max())) {
    234     LOG(FATAL) << "invalid main tid: " << argv[1];
    235   }
    236 
    237   if (!android::base::ParseInt(argv[2], &pseudothread_tid, 1, std::numeric_limits<pid_t>::max())) {
    238     LOG(FATAL) << "invalid pseudothread tid: " << argv[2];
    239   }
    240 
    241   if (!android::base::ParseInt(argv[3], &dump_type, 0, 1)) {
    242     LOG(FATAL) << "invalid requested dump type: " << argv[3];
    243   }
    244 
    245   if (target == 1) {
    246     LOG(FATAL) << "target died before we could attach (received main tid = " << main_tid << ")";
    247   }
    248 
    249   android::procinfo::ProcessInfo target_info;
    250   if (!android::procinfo::GetProcessInfo(main_tid, &target_info)) {
    251     LOG(FATAL) << "failed to fetch process info for target " << main_tid;
    252   }
    253 
    254   if (main_tid != target_info.tid || target != target_info.pid) {
    255     LOG(FATAL) << "target info mismatch, expected pid " << target << ", tid " << main_tid
    256                << ", received pid " << target_info.pid << ", tid " << target_info.tid;
    257   }
    258 
    259   // Open /proc/`getppid()` in the original process, and pass it down to the forked child.
    260   std::string target_proc_path = "/proc/" + std::to_string(target);
    261   int target_proc_fd = open(target_proc_path.c_str(), O_DIRECTORY | O_RDONLY);
    262   if (target_proc_fd == -1) {
    263     PLOG(FATAL) << "failed to open " << target_proc_path;
    264   }
    265 
    266   // Make sure our parent didn't die.
    267   if (getppid() != target) {
    268     PLOG(FATAL) << "parent died";
    269   }
    270 
    271   atrace_end(ATRACE_TAG);
    272 
    273   // Reparent ourselves to init, so that the signal handler can waitpid on the
    274   // original process to avoid leaving a zombie for non-fatal dumps.
    275   pid_t forkpid = fork();
    276   if (forkpid == -1) {
    277     PLOG(FATAL) << "fork failed";
    278   } else if (forkpid != 0) {
    279     exit(0);
    280   }
    281 
    282   ATRACE_NAME("after reparent");
    283 
    284   // Die if we take too long.
    285   //
    286   // Note: processes with many threads and minidebug-info can take a bit to
    287   //       unwind, do not make this too small. b/62828735
    288   alarm(5);
    289 
    290   std::string attach_error;
    291 
    292   std::map<pid_t, std::string> threads;
    293 
    294   {
    295     ATRACE_NAME("ptrace");
    296     // Seize the main thread.
    297     if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
    298       LOG(FATAL) << attach_error;
    299     }
    300 
    301     // Seize the siblings.
    302     {
    303       std::set<pid_t> siblings;
    304       if (!android::procinfo::GetProcessTids(target, &siblings)) {
    305         PLOG(FATAL) << "failed to get process siblings";
    306       }
    307 
    308       // but not the already attached main thread.
    309       siblings.erase(main_tid);
    310       // or the handler pseudothread.
    311       siblings.erase(pseudothread_tid);
    312 
    313       for (pid_t sibling_tid : siblings) {
    314         if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
    315           LOG(WARNING) << attach_error;
    316         } else {
    317           threads.emplace(sibling_tid, get_thread_name(sibling_tid));
    318         }
    319       }
    320     }
    321   }
    322 
    323   // Collect the backtrace map, open files, and process/thread names, while we still have caps.
    324   std::unique_ptr<BacktraceMap> backtrace_map;
    325   {
    326     ATRACE_NAME("backtrace map");
    327     backtrace_map.reset(BacktraceMap::Create(main_tid));
    328     if (!backtrace_map) {
    329       LOG(FATAL) << "failed to create backtrace map";
    330     }
    331   }
    332 
    333   // Collect the list of open files.
    334   OpenFilesList open_files;
    335   {
    336     ATRACE_NAME("open files");
    337     populate_open_files_list(target, &open_files);
    338   }
    339 
    340   std::string process_name = get_process_name(main_tid);
    341   threads.emplace(main_tid, get_thread_name(main_tid));
    342 
    343   // Drop our capabilities now that we've attached to the threads we care about.
    344   drop_capabilities();
    345 
    346   {
    347     ATRACE_NAME("tombstoned_connect");
    348     const DebuggerdDumpType dump_type_enum = static_cast<DebuggerdDumpType>(dump_type);
    349     LOG(INFO) << "obtaining output fd from tombstoned, type: " << dump_type_enum;
    350     tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum);
    351   }
    352 
    353   // Write a '\1' to stdout to tell the crashing process to resume.
    354   // It also restores the value of PR_SET_DUMPABLE at this point.
    355   if (TEMP_FAILURE_RETRY(write(STDOUT_FILENO, "\1", 1)) == -1) {
    356     PLOG(ERROR) << "failed to communicate to target process";
    357   }
    358 
    359   if (tombstoned_connected) {
    360     if (TEMP_FAILURE_RETRY(dup2(output_fd.get(), STDOUT_FILENO)) == -1) {
    361       PLOG(ERROR) << "failed to dup2 output fd (" << output_fd.get() << ") to STDOUT_FILENO";
    362     }
    363   } else {
    364     unique_fd devnull(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)));
    365     TEMP_FAILURE_RETRY(dup2(devnull.get(), STDOUT_FILENO));
    366     output_fd = std::move(devnull);
    367   }
    368 
    369   LOG(INFO) << "performing dump of process " << target << " (target tid = " << main_tid << ")";
    370 
    371   // At this point, the thread that made the request has been attached and is
    372   // in ptrace-stopped state. After resumption, the triggering signal that has
    373   // been queued will be delivered.
    374   if (ptrace(PTRACE_CONT, main_tid, 0, 0) != 0) {
    375     PLOG(ERROR) << "PTRACE_CONT(" << main_tid << ") failed";
    376     exit(1);
    377   }
    378 
    379   siginfo_t siginfo = {};
    380   {
    381     ATRACE_NAME("wait_for_signal");
    382     if (!wait_for_signal(main_tid, &siginfo)) {
    383       printf("failed to wait for signal in tid %d: %s\n", main_tid, strerror(errno));
    384       exit(1);
    385     }
    386   }
    387 
    388   int signo = siginfo.si_signo;
    389   bool fatal_signal = signo != DEBUGGER_SIGNAL;
    390   bool backtrace = false;
    391   uintptr_t abort_address = 0;
    392 
    393   // si_value can represent three things:
    394   //   0: dump tombstone
    395   //   1: dump backtrace
    396   //   everything else: abort message address (implies dump tombstone)
    397   if (siginfo.si_value.sival_int == 1) {
    398     backtrace = true;
    399   } else if (siginfo.si_value.sival_ptr != nullptr) {
    400     abort_address = reinterpret_cast<uintptr_t>(siginfo.si_value.sival_ptr);
    401   }
    402 
    403   // TODO: Use seccomp to lock ourselves down.
    404 
    405   std::string amfd_data;
    406   if (backtrace) {
    407     ATRACE_NAME("dump_backtrace");
    408     dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, process_name, threads, 0);
    409   } else {
    410     ATRACE_NAME("engrave_tombstone");
    411     engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid,
    412                       process_name, threads, abort_address, fatal_signal ? &amfd_data : nullptr);
    413   }
    414 
    415   // We don't actually need to PTRACE_DETACH, as long as our tracees aren't in
    416   // group-stop state, which is true as long as no stopping signals are sent.
    417 
    418   bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false);
    419   if (!fatal_signal || siginfo.si_code == SI_USER) {
    420     // Don't wait_for_gdb when the process didn't actually crash.
    421     wait_for_gdb = false;
    422   }
    423 
    424   // If the process crashed or we need to send it SIGSTOP for wait_for_gdb,
    425   // get it in a state where it can receive signals, and then send the relevant
    426   // signal.
    427   if (wait_for_gdb || fatal_signal) {
    428     if (ptrace(PTRACE_INTERRUPT, main_tid, 0, 0) != 0) {
    429       PLOG(ERROR) << "failed to use PTRACE_INTERRUPT on " << main_tid;
    430     }
    431 
    432     if (tgkill(target, main_tid, wait_for_gdb ? SIGSTOP : signo) != 0) {
    433       PLOG(ERROR) << "failed to resend signal " << signo << " to " << main_tid;
    434     }
    435   }
    436 
    437   if (wait_for_gdb) {
    438     // Use ALOGI to line up with output from engrave_tombstone.
    439     ALOGI(
    440       "***********************************************************\n"
    441       "* Process %d has been suspended while crashing.\n"
    442       "* To attach gdbserver and start gdb, run this on the host:\n"
    443       "*\n"
    444       "*     gdbclient.py -p %d\n"
    445       "*\n"
    446       "***********************************************************",
    447       target, main_tid);
    448   }
    449 
    450   if (fatal_signal) {
    451     // Don't try to notify ActivityManager if it just crashed, or we might hang until timeout.
    452     if (target_info.name != "system_server" || target_info.uid != AID_SYSTEM) {
    453       activity_manager_notify(target, signo, amfd_data);
    454     }
    455   }
    456 
    457   // Close stdout before we notify tombstoned of completion.
    458   close(STDOUT_FILENO);
    459   if (tombstoned_connected && !tombstoned_notify_completion(tombstoned_socket.get())) {
    460     LOG(ERROR) << "failed to notify tombstoned of completion";
    461   }
    462 
    463   return 0;
    464 }
    465