• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
set_signal_sender_process_name()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.
start_signal_sender()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 
stop_signal_sender()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 
send_signal(pid_t pid,pid_t tid,int signal)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