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 <stdlib.h> 20#include <string.h> 21#include <sys/socket.h> 22#include <sys/syscall.h> 23#include <sys/types.h> 24#include <sys/wait.h> 25#include <unistd.h> 26 27#include <log/logger.h> 28 29#include "signal_sender.h" 30 31static int signal_fd = -1; 32static pid_t signal_pid; 33struct signal_message { 34 pid_t pid; 35 pid_t tid; 36 int signal; 37}; 38 39static void set_signal_sender_process_name() { 40#if defined(__LP64__) 41 static constexpr char long_process_name[] = "debuggerd64:signaller"; 42 static constexpr char short_process_name[] = "debuggerd64:sig"; 43 static_assert(sizeof(long_process_name) <= sizeof("/system/bin/debuggerd64"), ""); 44#else 45 static constexpr char long_process_name[] = "debuggerd:signaller"; 46 static constexpr char short_process_name[] = "debuggerd:sig"; 47 static_assert(sizeof(long_process_name) <= sizeof("/system/bin/debuggerd"), ""); 48#endif 49 50 // pthread_setname_np has a maximum length of 16 chars, including null terminator. 51 static_assert(sizeof(short_process_name) <= 16, ""); 52 pthread_setname_np(pthread_self(), short_process_name); 53 54 char* progname = const_cast<char*>(getprogname()); 55 if (strlen(progname) <= strlen(long_process_name)) { 56 ALOGE("debuggerd: unexpected progname %s", progname); 57 return; 58 } 59 60 memset(progname, 0, strlen(progname)); 61 strcpy(progname, long_process_name); 62} 63 64// Fork a process to send signals for the worker processes to use after they've dropped privileges. 65bool start_signal_sender() { 66 if (signal_pid != 0) { 67 ALOGE("debuggerd: attempted to start signal sender multiple times"); 68 return false; 69 } 70 71 int sfd[2]; 72 if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sfd) != 0) { 73 ALOGE("debuggerd: failed to create socketpair for signal sender: %s", strerror(errno)); 74 return false; 75 } 76 77 pid_t parent = getpid(); 78 pid_t fork_pid = fork(); 79 if (fork_pid == -1) { 80 ALOGE("debuggerd: failed to initialize signal sender: fork failed: %s", strerror(errno)); 81 return false; 82 } else if (fork_pid == 0) { 83 close(sfd[1]); 84 85 set_signal_sender_process_name(); 86 87 while (true) { 88 signal_message msg; 89 int rc = TEMP_FAILURE_RETRY(read(sfd[0], &msg, sizeof(msg))); 90 if (rc < 0) { 91 ALOGE("debuggerd: signal sender failed to read from socket"); 92 break; 93 } else if (rc != sizeof(msg)) { 94 ALOGE("debuggerd: signal sender read unexpected number of bytes: %d", rc); 95 break; 96 } 97 98 // Report success after sending a signal 99 int err = 0; 100 if (msg.tid > 0) { 101 if (syscall(SYS_tgkill, msg.pid, msg.tid, msg.signal) != 0) { 102 err = errno; 103 } 104 } else { 105 if (kill(msg.pid, msg.signal) != 0) { 106 err = errno; 107 } 108 } 109 110 if (TEMP_FAILURE_RETRY(write(sfd[0], &err, sizeof(err))) < 0) { 111 ALOGE("debuggerd: signal sender failed to write: %s", strerror(errno)); 112 } 113 } 114 115 // Our parent proably died, but if not, kill them. 116 if (getppid() == parent) { 117 kill(parent, SIGKILL); 118 } 119 _exit(1); 120 } else { 121 close(sfd[0]); 122 signal_fd = sfd[1]; 123 signal_pid = fork_pid; 124 return true; 125 } 126} 127 128bool stop_signal_sender() { 129 if (signal_pid <= 0) { 130 return false; 131 } 132 133 if (kill(signal_pid, SIGKILL) != 0) { 134 ALOGE("debuggerd: failed to kill signal sender: %s", strerror(errno)); 135 return false; 136 } 137 138 close(signal_fd); 139 signal_fd = -1; 140 141 int status; 142 waitpid(signal_pid, &status, 0); 143 signal_pid = 0; 144 145 return true; 146} 147 148bool send_signal(pid_t pid, pid_t tid, int signal) { 149 if (signal_fd == -1) { 150 ALOGE("debuggerd: attempted to send signal before signal sender was started"); 151 errno = EHOSTUNREACH; 152 return false; 153 } 154 155 signal_message msg = {.pid = pid, .tid = tid, .signal = signal }; 156 if (TEMP_FAILURE_RETRY(write(signal_fd, &msg, sizeof(msg))) < 0) { 157 ALOGE("debuggerd: failed to send message to signal sender: %s", strerror(errno)); 158 errno = EHOSTUNREACH; 159 return false; 160 } 161 162 int response; 163 ssize_t rc = TEMP_FAILURE_RETRY(read(signal_fd, &response, sizeof(response))); 164 if (rc == 0) { 165 ALOGE("debuggerd: received EOF from signal sender"); 166 errno = EHOSTUNREACH; 167 return false; 168 } else if (rc < 0) { 169 ALOGE("debuggerd: failed to receive response from signal sender: %s", strerror(errno)); 170 errno = EHOSTUNREACH; 171 return false; 172 } 173 174 if (response == 0) { 175 return true; 176 } 177 178 errno = response; 179 return false; 180} 181