Loading adb/Android.bp +60 −5 Original line number Diff line number Diff line Loading @@ -114,6 +114,61 @@ cc_defaults { }, } // libadbconnection // ========================================================= // libadbconnection_client/server implement the socket handling for jdwp // forwarding and the track-jdwp service. cc_library { name: "libadbconnection_server", srcs: ["adbconnection/adbconnection_server.cpp"], export_include_dirs: ["adbconnection/include"], stl: "libc++_static", shared_libs: ["liblog"], static_libs: ["libbase"], defaults: ["adbd_defaults", "host_adbd_supported"], // Avoid getting duplicate symbol of android::build::getbuildnumber(). use_version_lib: false, recovery_available: true, compile_multilib: "both", } cc_library { name: "libadbconnection_client", srcs: ["adbconnection/adbconnection_client.cpp"], export_include_dirs: ["adbconnection/include"], stl: "libc++_static", shared_libs: ["liblog"], static_libs: ["libbase"], defaults: ["adbd_defaults"], visibility: [ "//art:__subpackages__", "//system/core/adb/apex:__subpackages__", ], apex_available: [ "com.android.adbd", "test_com.android.adbd", ], // libadbconnection_client doesn't need an embedded build number. use_version_lib: false, stubs: { symbol_file: "adbconnection/libadbconnection_client.map.txt", versions: ["1"], }, host_supported: true, compile_multilib: "both", } // libadb // ========================================================= // These files are compiled for both the host and the device. Loading Loading @@ -358,11 +413,11 @@ cc_library_static { generated_headers: ["platform_tools_version"], static_libs: [ "libadbconnection_server", "libdiagnose_usb", ], shared_libs: [ "libadbconnection_server", "libadbd_auth", "libasyncio", "libbase", Loading Loading @@ -411,12 +466,12 @@ cc_library { ], static_libs: [ "libadbconnection_server", "libadbd_core", "libdiagnose_usb", ], shared_libs: [ "libadbconnection_server", "libadbd_auth", "libasyncio", "libbase", Loading Loading @@ -452,7 +507,7 @@ cc_library { defaults: ["adbd_defaults", "host_adbd_supported"], recovery_available: true, // Avoid getting duplicate symbol of android::build::GetBuildNumber(). // avoid getting duplicate symbol of android::build::getbuildnumber(). use_version_lib: false, // libminadbd wants both, as it's used to build native tests. Loading @@ -460,11 +515,11 @@ cc_library { // libadbd doesn't build any additional source, but to expose libadbd_core as a shared library. whole_static_libs: [ "libadbconnection_server", "libadbd_core", ], shared_libs: [ "libadbconnection_server", "libadbd_auth", "libadbd_services", "libasyncio", Loading Loading @@ -500,6 +555,7 @@ cc_binary { stl: "libc++_static", static_libs: [ "libadbconnection_server", "libadbd", "libadbd_auth", "libadbd_services", Loading @@ -516,7 +572,6 @@ cc_binary { ], shared_libs: [ "libadbconnection_server", "libcrypto", ], } Loading adb/adbconnection/.clang-format 0 → 120000 +1 −0 Original line number Diff line number Diff line ../../.clang-format-2 No newline at end of file adb/adbconnection/adbconnection_client.cpp 0 → 100644 +148 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "adbconnection/client.h" #include <pwd.h> #include <stddef.h> #include <stdint.h> #include <sys/socket.h> #include <sys/un.h> #include <memory> #include <optional> #include <android-base/cmsg.h> #include <android-base/logging.h> #include <android-base/unique_fd.h> using android::base::unique_fd; static constexpr char kJdwpControlName[] = "\0jdwp-control"; struct AdbConnectionClientContext { unique_fd control_socket_; }; bool SocketPeerIsTrusted(int fd) { ucred cr; socklen_t cr_length = sizeof(cr); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_length) != 0) { PLOG(ERROR) << "couldn't get socket credentials"; return false; } passwd* shell = getpwnam("shell"); if (cr.uid != 0 && cr.uid != shell->pw_uid) { LOG(ERROR) << "untrusted uid " << cr.uid << " on other end of socket"; return false; } return true; } AdbConnectionClientContext* adbconnection_client_new( const AdbConnectionClientInfo* const* info_elems, size_t info_count) { auto ctx = std::make_unique<AdbConnectionClientContext>(); std::optional<uint64_t> pid; std::optional<bool> debuggable; for (size_t i = 0; i < info_count; ++i) { auto info = info_elems[i]; switch (info->type) { case AdbConnectionClientInfoType::pid: if (pid) { LOG(ERROR) << "multiple pid entries in AdbConnectionClientInfo, ignoring"; continue; } pid = info->data.pid; break; case AdbConnectionClientInfoType::debuggable: if (debuggable) { LOG(ERROR) << "multiple debuggable entries in AdbConnectionClientInfo, ignoring"; continue; } debuggable = info->data.pid; break; } } if (!pid) { LOG(ERROR) << "AdbConnectionClientInfo missing required field pid"; return nullptr; } if (!debuggable) { LOG(ERROR) << "AdbConnectionClientInfo missing required field debuggable"; return nullptr; } ctx->control_socket_.reset(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0)); if (ctx->control_socket_ < 0) { PLOG(ERROR) << "failed to create Unix domain socket"; return nullptr; } struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; setsockopt(ctx->control_socket_.get(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); sockaddr_un addr = {}; addr.sun_family = AF_UNIX; memcpy(addr.sun_path, kJdwpControlName, sizeof(kJdwpControlName)); size_t addr_len = offsetof(sockaddr_un, sun_path) + sizeof(kJdwpControlName) - 1; int rc = connect(ctx->control_socket_.get(), reinterpret_cast<sockaddr*>(&addr), addr_len); if (rc != 0) { PLOG(ERROR) << "failed to connect to jdwp control socket"; return nullptr; } bool trusted = SocketPeerIsTrusted(ctx->control_socket_.get()); if (!trusted) { LOG(ERROR) << "adb socket is not trusted, aborting connection"; return nullptr; } uint32_t pid_u32 = static_cast<uint32_t>(*pid); rc = TEMP_FAILURE_RETRY(write(ctx->control_socket_.get(), &pid_u32, sizeof(pid_u32))); if (rc != sizeof(pid_u32)) { PLOG(ERROR) << "failed to send JDWP process pid to adbd"; } return ctx.release(); } void adbconnection_client_destroy(AdbConnectionClientContext* ctx) { delete ctx; } int adbconnection_client_pollfd(AdbConnectionClientContext* ctx) { return ctx->control_socket_.get(); } int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx) { char dummy; unique_fd jdwp_fd; ssize_t rc = android::base::ReceiveFileDescriptors(ctx->control_socket_, &dummy, 1, &jdwp_fd); if (rc != 1) { return rc; } return jdwp_fd.release(); } adb/adbconnection/adbconnection_server.cpp 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "adbconnection/server.h" #include <sys/epoll.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <algorithm> #include <array> #include <vector> #include <android-base/logging.h> #include <android-base/unique_fd.h> using android::base::unique_fd; #define JDWP_CONTROL_NAME "\0jdwp-control" #define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1) static_assert(JDWP_CONTROL_NAME_LEN <= sizeof(reinterpret_cast<sockaddr_un*>(0)->sun_path)); // Listen for incoming jdwp clients forever. void adbconnection_listen(void (*callback)(int fd, pid_t pid)) { sockaddr_un addr = {}; socklen_t addrlen = JDWP_CONTROL_NAME_LEN + sizeof(addr.sun_family); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN); unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); if (s < 0) { PLOG(ERROR) << "failed to create JDWP control socket"; return; } if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) { PLOG(ERROR) << "failed to bind JDWP control socket"; return; } if (listen(s.get(), 4) < 0) { PLOG(ERROR) << "failed to listen on JDWP control socket"; return; } std::vector<unique_fd> pending_connections; unique_fd epfd(epoll_create1(EPOLL_CLOEXEC)); std::array<epoll_event, 16> events; events[0].events = EPOLLIN; events[0].data.fd = -1; if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, s.get(), &events[0]) != 0) { LOG(FATAL) << "failed to register event with epoll fd"; } while (true) { int epoll_rc = TEMP_FAILURE_RETRY(epoll_wait(epfd.get(), events.data(), events.size(), -1)); if (epoll_rc == -1) { PLOG(FATAL) << "epoll_wait failed"; } for (int i = 0; i < epoll_rc; ++i) { const epoll_event& event = events[i]; if (event.data.fd == -1) { unique_fd client( TEMP_FAILURE_RETRY(accept4(s.get(), nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC))); if (client == -1) { PLOG(WARNING) << "failed to accept client on JDWP control socket"; continue; } epoll_event register_event; register_event.events = EPOLLIN; register_event.data.fd = client.get(); if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, client.get(), ®ister_event) != 0) { PLOG(FATAL) << "failed to register JDWP client with epoll"; } pending_connections.emplace_back(std::move(client)); } else { // n^2, but the backlog should be short. auto it = std::find_if(pending_connections.begin(), pending_connections.end(), [&](const unique_fd& fd) { return fd.get() == event.data.fd; }); if (it == pending_connections.end()) { LOG(FATAL) << "failed to find JDWP client (" << event.data.fd << ") in pending connections"; } // Massively oversized buffer: we're expecting an int32_t from the other end. char buf[32]; int rc = TEMP_FAILURE_RETRY(recv(it->get(), buf, sizeof(buf), MSG_DONTWAIT)); if (rc != 4) { LOG(ERROR) << "received data of incorrect size from JDWP client: read " << rc << ", expected 4"; } else { int32_t pid; memcpy(&pid, buf, sizeof(pid)); callback(it->release(), static_cast<pid_t>(pid)); } if (epoll_ctl(epfd.get(), EPOLL_CTL_DEL, event.data.fd, nullptr) != 0) { LOG(FATAL) << "failed to delete fd from JDWP epoll fd"; } pending_connections.erase(it); } } } } adb/adbconnection/include/adbconnection/client.h 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <stdint.h> #include <sys/types.h> #include <android-base/unique_fd.h> extern "C" { struct AdbConnectionClientContext; enum AdbConnectionClientInfoType { pid, debuggable, }; struct AdbConnectionClientInfo { AdbConnectionClientInfoType type; union { uint64_t pid; bool debuggable; } data; }; // Construct a context and connect to adbd. // Returns null if we fail to connect to adbd. AdbConnectionClientContext* adbconnection_client_new( const AdbConnectionClientInfo* const* info_elems, size_t info_count); void adbconnection_client_destroy(AdbConnectionClientContext* ctx); // Get an fd which can be polled upon to detect when a jdwp socket is available. // You do not own this fd. Do not close it. int adbconnection_client_pollfd(AdbConnectionClientContext* ctx); // Receive a jdwp client fd. // Ownership is transferred to the caller of this function. int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx); } Loading
adb/Android.bp +60 −5 Original line number Diff line number Diff line Loading @@ -114,6 +114,61 @@ cc_defaults { }, } // libadbconnection // ========================================================= // libadbconnection_client/server implement the socket handling for jdwp // forwarding and the track-jdwp service. cc_library { name: "libadbconnection_server", srcs: ["adbconnection/adbconnection_server.cpp"], export_include_dirs: ["adbconnection/include"], stl: "libc++_static", shared_libs: ["liblog"], static_libs: ["libbase"], defaults: ["adbd_defaults", "host_adbd_supported"], // Avoid getting duplicate symbol of android::build::getbuildnumber(). use_version_lib: false, recovery_available: true, compile_multilib: "both", } cc_library { name: "libadbconnection_client", srcs: ["adbconnection/adbconnection_client.cpp"], export_include_dirs: ["adbconnection/include"], stl: "libc++_static", shared_libs: ["liblog"], static_libs: ["libbase"], defaults: ["adbd_defaults"], visibility: [ "//art:__subpackages__", "//system/core/adb/apex:__subpackages__", ], apex_available: [ "com.android.adbd", "test_com.android.adbd", ], // libadbconnection_client doesn't need an embedded build number. use_version_lib: false, stubs: { symbol_file: "adbconnection/libadbconnection_client.map.txt", versions: ["1"], }, host_supported: true, compile_multilib: "both", } // libadb // ========================================================= // These files are compiled for both the host and the device. Loading Loading @@ -358,11 +413,11 @@ cc_library_static { generated_headers: ["platform_tools_version"], static_libs: [ "libadbconnection_server", "libdiagnose_usb", ], shared_libs: [ "libadbconnection_server", "libadbd_auth", "libasyncio", "libbase", Loading Loading @@ -411,12 +466,12 @@ cc_library { ], static_libs: [ "libadbconnection_server", "libadbd_core", "libdiagnose_usb", ], shared_libs: [ "libadbconnection_server", "libadbd_auth", "libasyncio", "libbase", Loading Loading @@ -452,7 +507,7 @@ cc_library { defaults: ["adbd_defaults", "host_adbd_supported"], recovery_available: true, // Avoid getting duplicate symbol of android::build::GetBuildNumber(). // avoid getting duplicate symbol of android::build::getbuildnumber(). use_version_lib: false, // libminadbd wants both, as it's used to build native tests. Loading @@ -460,11 +515,11 @@ cc_library { // libadbd doesn't build any additional source, but to expose libadbd_core as a shared library. whole_static_libs: [ "libadbconnection_server", "libadbd_core", ], shared_libs: [ "libadbconnection_server", "libadbd_auth", "libadbd_services", "libasyncio", Loading Loading @@ -500,6 +555,7 @@ cc_binary { stl: "libc++_static", static_libs: [ "libadbconnection_server", "libadbd", "libadbd_auth", "libadbd_services", Loading @@ -516,7 +572,6 @@ cc_binary { ], shared_libs: [ "libadbconnection_server", "libcrypto", ], } Loading
adb/adbconnection/.clang-format 0 → 120000 +1 −0 Original line number Diff line number Diff line ../../.clang-format-2 No newline at end of file
adb/adbconnection/adbconnection_client.cpp 0 → 100644 +148 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "adbconnection/client.h" #include <pwd.h> #include <stddef.h> #include <stdint.h> #include <sys/socket.h> #include <sys/un.h> #include <memory> #include <optional> #include <android-base/cmsg.h> #include <android-base/logging.h> #include <android-base/unique_fd.h> using android::base::unique_fd; static constexpr char kJdwpControlName[] = "\0jdwp-control"; struct AdbConnectionClientContext { unique_fd control_socket_; }; bool SocketPeerIsTrusted(int fd) { ucred cr; socklen_t cr_length = sizeof(cr); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_length) != 0) { PLOG(ERROR) << "couldn't get socket credentials"; return false; } passwd* shell = getpwnam("shell"); if (cr.uid != 0 && cr.uid != shell->pw_uid) { LOG(ERROR) << "untrusted uid " << cr.uid << " on other end of socket"; return false; } return true; } AdbConnectionClientContext* adbconnection_client_new( const AdbConnectionClientInfo* const* info_elems, size_t info_count) { auto ctx = std::make_unique<AdbConnectionClientContext>(); std::optional<uint64_t> pid; std::optional<bool> debuggable; for (size_t i = 0; i < info_count; ++i) { auto info = info_elems[i]; switch (info->type) { case AdbConnectionClientInfoType::pid: if (pid) { LOG(ERROR) << "multiple pid entries in AdbConnectionClientInfo, ignoring"; continue; } pid = info->data.pid; break; case AdbConnectionClientInfoType::debuggable: if (debuggable) { LOG(ERROR) << "multiple debuggable entries in AdbConnectionClientInfo, ignoring"; continue; } debuggable = info->data.pid; break; } } if (!pid) { LOG(ERROR) << "AdbConnectionClientInfo missing required field pid"; return nullptr; } if (!debuggable) { LOG(ERROR) << "AdbConnectionClientInfo missing required field debuggable"; return nullptr; } ctx->control_socket_.reset(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0)); if (ctx->control_socket_ < 0) { PLOG(ERROR) << "failed to create Unix domain socket"; return nullptr; } struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; setsockopt(ctx->control_socket_.get(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); sockaddr_un addr = {}; addr.sun_family = AF_UNIX; memcpy(addr.sun_path, kJdwpControlName, sizeof(kJdwpControlName)); size_t addr_len = offsetof(sockaddr_un, sun_path) + sizeof(kJdwpControlName) - 1; int rc = connect(ctx->control_socket_.get(), reinterpret_cast<sockaddr*>(&addr), addr_len); if (rc != 0) { PLOG(ERROR) << "failed to connect to jdwp control socket"; return nullptr; } bool trusted = SocketPeerIsTrusted(ctx->control_socket_.get()); if (!trusted) { LOG(ERROR) << "adb socket is not trusted, aborting connection"; return nullptr; } uint32_t pid_u32 = static_cast<uint32_t>(*pid); rc = TEMP_FAILURE_RETRY(write(ctx->control_socket_.get(), &pid_u32, sizeof(pid_u32))); if (rc != sizeof(pid_u32)) { PLOG(ERROR) << "failed to send JDWP process pid to adbd"; } return ctx.release(); } void adbconnection_client_destroy(AdbConnectionClientContext* ctx) { delete ctx; } int adbconnection_client_pollfd(AdbConnectionClientContext* ctx) { return ctx->control_socket_.get(); } int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx) { char dummy; unique_fd jdwp_fd; ssize_t rc = android::base::ReceiveFileDescriptors(ctx->control_socket_, &dummy, 1, &jdwp_fd); if (rc != 1) { return rc; } return jdwp_fd.release(); }
adb/adbconnection/adbconnection_server.cpp 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "adbconnection/server.h" #include <sys/epoll.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <algorithm> #include <array> #include <vector> #include <android-base/logging.h> #include <android-base/unique_fd.h> using android::base::unique_fd; #define JDWP_CONTROL_NAME "\0jdwp-control" #define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1) static_assert(JDWP_CONTROL_NAME_LEN <= sizeof(reinterpret_cast<sockaddr_un*>(0)->sun_path)); // Listen for incoming jdwp clients forever. void adbconnection_listen(void (*callback)(int fd, pid_t pid)) { sockaddr_un addr = {}; socklen_t addrlen = JDWP_CONTROL_NAME_LEN + sizeof(addr.sun_family); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN); unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); if (s < 0) { PLOG(ERROR) << "failed to create JDWP control socket"; return; } if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) { PLOG(ERROR) << "failed to bind JDWP control socket"; return; } if (listen(s.get(), 4) < 0) { PLOG(ERROR) << "failed to listen on JDWP control socket"; return; } std::vector<unique_fd> pending_connections; unique_fd epfd(epoll_create1(EPOLL_CLOEXEC)); std::array<epoll_event, 16> events; events[0].events = EPOLLIN; events[0].data.fd = -1; if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, s.get(), &events[0]) != 0) { LOG(FATAL) << "failed to register event with epoll fd"; } while (true) { int epoll_rc = TEMP_FAILURE_RETRY(epoll_wait(epfd.get(), events.data(), events.size(), -1)); if (epoll_rc == -1) { PLOG(FATAL) << "epoll_wait failed"; } for (int i = 0; i < epoll_rc; ++i) { const epoll_event& event = events[i]; if (event.data.fd == -1) { unique_fd client( TEMP_FAILURE_RETRY(accept4(s.get(), nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC))); if (client == -1) { PLOG(WARNING) << "failed to accept client on JDWP control socket"; continue; } epoll_event register_event; register_event.events = EPOLLIN; register_event.data.fd = client.get(); if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, client.get(), ®ister_event) != 0) { PLOG(FATAL) << "failed to register JDWP client with epoll"; } pending_connections.emplace_back(std::move(client)); } else { // n^2, but the backlog should be short. auto it = std::find_if(pending_connections.begin(), pending_connections.end(), [&](const unique_fd& fd) { return fd.get() == event.data.fd; }); if (it == pending_connections.end()) { LOG(FATAL) << "failed to find JDWP client (" << event.data.fd << ") in pending connections"; } // Massively oversized buffer: we're expecting an int32_t from the other end. char buf[32]; int rc = TEMP_FAILURE_RETRY(recv(it->get(), buf, sizeof(buf), MSG_DONTWAIT)); if (rc != 4) { LOG(ERROR) << "received data of incorrect size from JDWP client: read " << rc << ", expected 4"; } else { int32_t pid; memcpy(&pid, buf, sizeof(pid)); callback(it->release(), static_cast<pid_t>(pid)); } if (epoll_ctl(epfd.get(), EPOLL_CTL_DEL, event.data.fd, nullptr) != 0) { LOG(FATAL) << "failed to delete fd from JDWP epoll fd"; } pending_connections.erase(it); } } } }
adb/adbconnection/include/adbconnection/client.h 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <stdint.h> #include <sys/types.h> #include <android-base/unique_fd.h> extern "C" { struct AdbConnectionClientContext; enum AdbConnectionClientInfoType { pid, debuggable, }; struct AdbConnectionClientInfo { AdbConnectionClientInfoType type; union { uint64_t pid; bool debuggable; } data; }; // Construct a context and connect to adbd. // Returns null if we fail to connect to adbd. AdbConnectionClientContext* adbconnection_client_new( const AdbConnectionClientInfo* const* info_elems, size_t info_count); void adbconnection_client_destroy(AdbConnectionClientContext* ctx); // Get an fd which can be polled upon to detect when a jdwp socket is available. // You do not own this fd. Do not close it. int adbconnection_client_pollfd(AdbConnectionClientContext* ctx); // Receive a jdwp client fd. // Ownership is transferred to the caller of this function. int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx); }