1 /* 2 * Copyright (C) 2020 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 "adbconnection/client.h" 18 19 #include <pwd.h> 20 #include <stddef.h> 21 #include <stdint.h> 22 #include <sys/socket.h> 23 #include <sys/un.h> 24 25 #include <memory> 26 #include <optional> 27 28 #include <android-base/cmsg.h> 29 #include <android-base/logging.h> 30 #include <android-base/properties.h> 31 #include <android-base/unique_fd.h> 32 33 #include "adbconnection/process_info.h" 34 35 using android::base::unique_fd; 36 37 static constexpr char kJdwpControlName[] = "\0jdwp-control"; 38 39 struct AdbConnectionClientContext { 40 unique_fd control_socket_; 41 }; 42 43 bool SocketPeerIsTrusted(int fd) { 44 ucred cr; 45 socklen_t cr_length = sizeof(cr); 46 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_length) != 0) { 47 PLOG(ERROR) << "couldn't get socket credentials"; 48 return false; 49 } 50 51 passwd* shell = getpwnam("shell"); 52 if (cr.uid != 0 && cr.uid != shell->pw_uid) { 53 LOG(ERROR) << "untrusted uid " << cr.uid << " on other end of socket"; 54 return false; 55 } 56 57 return true; 58 } 59 60 AdbConnectionClientContext* adbconnection_client_new( 61 const AdbConnectionClientInfo* const* info_elems, size_t info_count) { 62 auto ctx = std::make_unique<AdbConnectionClientContext>(); 63 64 std::optional<uint64_t> pid; 65 std::optional<bool> debuggable; 66 std::optional<bool> profileable; 67 std::optional<std::string> architecture; 68 69 for (size_t i = 0; i < info_count; ++i) { 70 auto info = info_elems[i]; 71 switch (info->type) { 72 case AdbConnectionClientInfoType::pid: 73 if (pid) { 74 LOG(ERROR) << "multiple pid entries in AdbConnectionClientInfo, ignoring"; 75 continue; 76 } 77 pid = info->data.pid; 78 break; 79 80 case AdbConnectionClientInfoType::debuggable: 81 if (debuggable) { 82 LOG(ERROR) << "multiple debuggable entries in AdbConnectionClientInfo, ignoring"; 83 continue; 84 } 85 debuggable = info->data.debuggable; 86 break; 87 88 case AdbConnectionClientInfoType::profileable: 89 if (profileable) { 90 LOG(ERROR) << "multiple profileable entries in AdbConnectionClientInfo, ignoring"; 91 continue; 92 } 93 profileable = info->data.profileable; 94 break; 95 96 case AdbConnectionClientInfoType::architecture: 97 if (architecture) { 98 LOG(ERROR) << "multiple architecture entries in AdbConnectionClientInfo, ignoring"; 99 continue; 100 } 101 architecture = std::string(info->data.architecture.name, info->data.architecture.size); 102 break; 103 } 104 } 105 106 if (!pid) { 107 LOG(ERROR) << "AdbConnectionClientInfo missing required field pid"; 108 return nullptr; 109 } 110 111 if (!debuggable) { 112 LOG(ERROR) << "AdbConnectionClientInfo missing required field debuggable"; 113 return nullptr; 114 } 115 116 if (!profileable) { 117 LOG(ERROR) << "AdbConnectionClientInfo missing required field profileable"; 118 return nullptr; 119 } 120 121 if (!architecture) { 122 LOG(ERROR) << "AdbConnectionClientInfo missing required field architecture"; 123 return nullptr; 124 } 125 126 ctx->control_socket_.reset(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0)); 127 if (ctx->control_socket_ < 0) { 128 PLOG(ERROR) << "failed to create Unix domain socket"; 129 return nullptr; 130 } 131 132 #if defined(__ANDROID__) 133 // It's possible that adbd isn't running at this point. 134 // We don't want to just blindly connect, because if there's nothing listening, we'll end up 135 // waking up every second and preventing the CPU from going to sleep. 136 if (!android::base::WaitForProperty("init.svc.adbd", "running")) { 137 LOG(ERROR) << "adbd isn't running"; 138 return nullptr; 139 } 140 #endif 141 142 struct timeval timeout; 143 timeout.tv_sec = 1; 144 timeout.tv_usec = 0; 145 setsockopt(ctx->control_socket_.get(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); 146 147 sockaddr_un addr = {}; 148 addr.sun_family = AF_UNIX; 149 memcpy(addr.sun_path, kJdwpControlName, sizeof(kJdwpControlName)); 150 size_t addr_len = offsetof(sockaddr_un, sun_path) + sizeof(kJdwpControlName) - 1; 151 152 int rc = connect(ctx->control_socket_.get(), reinterpret_cast<sockaddr*>(&addr), addr_len); 153 if (rc != 0) { 154 if (errno == ECONNREFUSED) { 155 // On userdebug devices, every Java process is debuggable, so if adbd is explicitly turned 156 // off, this would spew enormous amounts of red-herring errors. 157 LOG(DEBUG) << "failed to connect to jdwp control socket, adbd not running?"; 158 } else { 159 PLOG(ERROR) << "failed to connect to jdwp control socket"; 160 } 161 return nullptr; 162 } 163 164 bool trusted = SocketPeerIsTrusted(ctx->control_socket_.get()); 165 if (!trusted) { 166 LOG(ERROR) << "adb socket is not trusted, aborting connection"; 167 return nullptr; 168 } 169 170 ProcessInfo process(*pid, *debuggable, *profileable, *architecture); 171 rc = TEMP_FAILURE_RETRY(write(ctx->control_socket_.get(), &process, sizeof(process))); 172 if (rc != sizeof(process)) { 173 PLOG(ERROR) << "failed to send JDWP process info to adbd"; 174 } 175 176 return ctx.release(); 177 } 178 179 void adbconnection_client_destroy(AdbConnectionClientContext* ctx) { 180 delete ctx; 181 } 182 183 int adbconnection_client_pollfd(AdbConnectionClientContext* ctx) { 184 return ctx->control_socket_.get(); 185 } 186 187 int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx) { 188 char dummy; 189 unique_fd jdwp_fd; 190 ssize_t rc = android::base::ReceiveFileDescriptors(ctx->control_socket_, &dummy, 1, &jdwp_fd); 191 if (rc != 1) { 192 return rc; 193 } 194 return jdwp_fd.release(); 195 } 196