• 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 #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 
31 static int signal_fd = -1;
32 static pid_t signal_pid;
33 struct signal_message {
34   pid_t pid;
35   pid_t tid;
36   int signal;
37 };
38 
set_signal_sender_process_name()39 static 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.
start_signal_sender()65 bool 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 
stop_signal_sender()128 bool 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 
send_signal(pid_t pid,pid_t tid,int signal)148 bool 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