1 /* 2 * Copyright (C) 2018 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 TRACE_TAG SERVICES 18 19 #include "sysdeps.h" 20 21 #include <errno.h> 22 #include <netdb.h> 23 #include <netinet/in.h> 24 #include <stddef.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <sys/ioctl.h> 29 #include <sys/socket.h> 30 #include <sys/un.h> 31 #include <unistd.h> 32 33 #include <thread> 34 35 #include <android-base/file.h> 36 #include <android-base/parseint.h> 37 #include <android-base/parsenetaddress.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/android_reboot.h> 43 #include <cutils/sockets.h> 44 #include <log/log_properties.h> 45 46 #include "adb.h" 47 #include "adb_io.h" 48 #include "adb_unique_fd.h" 49 #include "adb_utils.h" 50 #include "services.h" 51 #include "socket_spec.h" 52 #include "sysdeps.h" 53 #include "transport.h" 54 55 #include "daemon/file_sync_service.h" 56 #include "daemon/framebuffer_service.h" 57 #include "daemon/logging.h" 58 #include "daemon/restart_service.h" 59 #include "daemon/shell_service.h" 60 61 void reconnect_service(unique_fd fd, atransport* t) { 62 WriteFdExactly(fd.get(), "done"); 63 kick_transport(t); 64 } 65 66 unique_fd reverse_service(std::string_view command, atransport* transport) { 67 // TODO: Switch handle_forward_request to std::string_view. 68 std::string str(command); 69 70 int s[2]; 71 if (adb_socketpair(s)) { 72 PLOG(ERROR) << "cannot create service socket pair."; 73 return unique_fd{}; 74 } 75 VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1]; 76 if (!handle_forward_request(str.c_str(), transport, s[1])) { 77 SendFail(s[1], "not a reverse forwarding command"); 78 } 79 adb_close(s[1]); 80 return unique_fd{s[0]}; 81 } 82 83 // Shell service string can look like: 84 // shell[,arg1,arg2,...]:[command] 85 unique_fd ShellService(std::string_view args, const atransport* transport) { 86 size_t delimiter_index = args.find(':'); 87 if (delimiter_index == std::string::npos) { 88 LOG(ERROR) << "No ':' found in shell service arguments: " << args; 89 return unique_fd{}; 90 } 91 92 // TODO: android::base::Split(const std::string_view&, ...) 93 std::string service_args(args.substr(0, delimiter_index)); 94 std::string command(args.substr(delimiter_index + 1)); 95 96 // Defaults: 97 // PTY for interactive, raw for non-interactive. 98 // No protocol. 99 // $TERM set to "dumb". 100 SubprocessType type(command.empty() ? SubprocessType::kPty : SubprocessType::kRaw); 101 SubprocessProtocol protocol = SubprocessProtocol::kNone; 102 std::string terminal_type = "dumb"; 103 104 for (const std::string& arg : android::base::Split(service_args, ",")) { 105 if (arg == kShellServiceArgRaw) { 106 type = SubprocessType::kRaw; 107 } else if (arg == kShellServiceArgPty) { 108 type = SubprocessType::kPty; 109 } else if (arg == kShellServiceArgShellProtocol) { 110 protocol = SubprocessProtocol::kShell; 111 } else if (arg.starts_with("TERM=")) { 112 terminal_type = arg.substr(strlen("TERM=")); 113 } else if (!arg.empty()) { 114 // This is not an error to allow for future expansion. 115 LOG(WARNING) << "Ignoring unknown shell service argument: " << arg; 116 } 117 } 118 119 return StartSubprocess(command, terminal_type.c_str(), type, protocol); 120 } 121 122 static void spin_service(unique_fd fd) { 123 if (!__android_log_is_debuggable()) { 124 WriteFdExactly(fd.get(), "refusing to spin on non-debuggable build\n"); 125 return; 126 } 127 128 // A service that creates an fdevent that's always pending, and then ignores it. 129 unique_fd pipe_read, pipe_write; 130 if (!Pipe(&pipe_read, &pipe_write)) { 131 WriteFdExactly(fd.get(), "failed to create pipe\n"); 132 return; 133 } 134 135 fdevent_run_on_main_thread([fd = pipe_read.release()]() { 136 fdevent* fde = fdevent_create( 137 fd, [](int, unsigned, void*) {}, nullptr); 138 fdevent_add(fde, FDE_READ); 139 }); 140 141 WriteFdExactly(fd.get(), "spinning\n"); 142 } 143 144 [[maybe_unused]] static unique_fd reboot_device(const std::string& name) { 145 #if defined(__ANDROID_RECOVERY__) 146 if (!__android_log_is_debuggable()) { 147 auto reboot_service = [name](unique_fd fd) { 148 std::string reboot_string = android::base::StringPrintf("reboot,%s", name.c_str()); 149 if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) { 150 WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str()); 151 return; 152 } 153 while (true) pause(); 154 }; 155 return create_service_thread("reboot", reboot_service); 156 } 157 #endif 158 // Fall through 159 std::string cmd = "/system/bin/reboot "; 160 cmd += name; 161 return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); 162 } 163 164 struct ServiceSocket : public asocket { 165 ServiceSocket() { 166 install_local_socket(this); 167 this->enqueue = [](asocket* self, apacket::payload_type data) { 168 return static_cast<ServiceSocket*>(self)->Enqueue(std::move(data)); 169 }; 170 this->ready = [](asocket* self) { return static_cast<ServiceSocket*>(self)->Ready(); }; 171 this->close = [](asocket* self) { return static_cast<ServiceSocket*>(self)->Close(); }; 172 } 173 virtual ~ServiceSocket() = default; 174 175 virtual int Enqueue(apacket::payload_type data) { return -1; } 176 virtual void Ready() {} 177 virtual void Close() { 178 if (peer) { 179 peer->peer = nullptr; 180 if (peer->shutdown) { 181 peer->shutdown(peer); 182 } 183 peer->close(peer); 184 } 185 186 remove_socket(this); 187 delete this; 188 } 189 }; 190 191 struct SinkSocket : public ServiceSocket { 192 explicit SinkSocket(size_t byte_count) { 193 LOG(INFO) << "Creating new SinkSocket with capacity " << byte_count; 194 bytes_left_ = byte_count; 195 } 196 197 virtual ~SinkSocket() { LOG(INFO) << "SinkSocket destroyed"; } 198 199 virtual int Enqueue(apacket::payload_type data) override final { 200 if (bytes_left_ <= data.size()) { 201 // Done reading. 202 Close(); 203 return -1; 204 } 205 206 bytes_left_ -= data.size(); 207 return 0; 208 } 209 210 size_t bytes_left_; 211 }; 212 213 struct SourceSocket : public ServiceSocket { 214 explicit SourceSocket(size_t byte_count) { 215 LOG(INFO) << "Creating new SourceSocket with capacity " << byte_count; 216 bytes_left_ = byte_count; 217 } 218 219 virtual ~SourceSocket() { LOG(INFO) << "SourceSocket destroyed"; } 220 221 void Ready() { 222 size_t len = std::min(bytes_left_, get_max_payload()); 223 if (len == 0) { 224 Close(); 225 return; 226 } 227 228 Block block(len); 229 memset(block.data(), 0, block.size()); 230 peer->enqueue(peer, std::move(block)); 231 bytes_left_ -= len; 232 } 233 234 int Enqueue(apacket::payload_type data) { return -1; } 235 236 size_t bytes_left_; 237 }; 238 239 asocket* daemon_service_to_socket(std::string_view name) { 240 if (name == "jdwp") { 241 return create_jdwp_service_socket(); 242 } else if (name == "track-jdwp") { 243 return create_jdwp_tracker_service_socket(); 244 } else if (name == "track-app") { 245 return create_app_tracker_service_socket(); 246 } else if (android::base::ConsumePrefix(&name, "sink:")) { 247 uint64_t byte_count = 0; 248 if (!ParseUint(&byte_count, name)) { 249 return nullptr; 250 } 251 return new SinkSocket(byte_count); 252 } else if (android::base::ConsumePrefix(&name, "source:")) { 253 uint64_t byte_count = 0; 254 if (!ParseUint(&byte_count, name)) { 255 return nullptr; 256 } 257 return new SourceSocket(byte_count); 258 } 259 260 return nullptr; 261 } 262 263 unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) { 264 ADB_LOG(Service) << "transport " << transport->serial_name() << " opening service " << name; 265 266 #if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__) 267 if (name.starts_with("abb:") || name.starts_with("abb_exec:")) { 268 return execute_abb_command(name); 269 } 270 #endif 271 272 #if defined(__ANDROID__) 273 if (name.starts_with("framebuffer:")) { 274 return create_service_thread("fb", framebuffer_service); 275 } else if (android::base::ConsumePrefix(&name, "remount:")) { 276 std::string cmd = "/system/bin/remount "; 277 cmd += name; 278 return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); 279 } else if (android::base::ConsumePrefix(&name, "reboot:")) { 280 return reboot_device(std::string(name)); 281 } else if (name.starts_with("root:")) { 282 return create_service_thread("root", restart_root_service); 283 } else if (name.starts_with("unroot:")) { 284 return create_service_thread("unroot", restart_unroot_service); 285 } else if (android::base::ConsumePrefix(&name, "backup:")) { 286 std::string cmd = "/system/bin/bu backup "; 287 cmd += name; 288 return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); 289 } else if (name.starts_with("restore:")) { 290 return StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw, 291 SubprocessProtocol::kNone); 292 } else if (name.starts_with("disable-verity:")) { 293 return StartSubprocess("/system/bin/disable-verity", nullptr, SubprocessType::kRaw, 294 SubprocessProtocol::kNone); 295 } else if (name.starts_with("enable-verity:")) { 296 return StartSubprocess("/system/bin/enable-verity", nullptr, SubprocessType::kRaw, 297 SubprocessProtocol::kNone); 298 } else if (android::base::ConsumePrefix(&name, "tcpip:")) { 299 std::string str(name); 300 301 int port; 302 if (sscanf(str.c_str(), "%d", &port) != 1) { 303 return unique_fd{}; 304 } 305 return create_service_thread("tcp", 306 std::bind(restart_tcp_service, std::placeholders::_1, port)); 307 } else if (name.starts_with("usb:")) { 308 return create_service_thread("usb", restart_usb_service); 309 } 310 #endif 311 312 if (android::base::ConsumePrefix(&name, "dev:")) { 313 return unique_fd{unix_open(name, O_RDWR | O_CLOEXEC)}; 314 } else if (android::base::ConsumePrefix(&name, "jdwp:")) { 315 pid_t pid; 316 if (!ParseUint(&pid, name)) { 317 return unique_fd{}; 318 } 319 return create_jdwp_connection_fd(pid); 320 } else if (android::base::ConsumePrefix(&name, "shell")) { 321 return ShellService(name, transport); 322 } else if (android::base::ConsumePrefix(&name, "exec:")) { 323 return StartSubprocess(std::string(name), nullptr, SubprocessType::kRaw, 324 SubprocessProtocol::kNone); 325 } else if (name.starts_with("sync:")) { 326 return create_service_thread("sync", file_sync_service); 327 } else if (android::base::ConsumePrefix(&name, "reverse:")) { 328 return reverse_service(name, transport); 329 } else if (name == "reconnect") { 330 return create_service_thread( 331 "reconnect", std::bind(reconnect_service, std::placeholders::_1, transport)); 332 } else if (name == "spin") { 333 return create_service_thread("spin", spin_service); 334 } 335 336 return unique_fd{}; 337 } 338