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