Loading adb/adb.cpp +6 −2 Original line number Original line Diff line number Diff line Loading @@ -337,9 +337,12 @@ void handle_packet(apacket *p, atransport *t) case ADB_AUTH_SIGNATURE: { case ADB_AUTH_SIGNATURE: { // TODO: Switch to string_view. // TODO: Switch to string_view. std::string signature(p->payload.begin(), p->payload.end()); std::string signature(p->payload.begin(), p->payload.end()); if (adbd_auth_verify(t->token, sizeof(t->token), signature)) { std::string auth_key; if (adbd_auth_verify(t->token, sizeof(t->token), signature, &auth_key)) { adbd_auth_verified(t); adbd_auth_verified(t); t->failed_auth_attempts = 0; t->failed_auth_attempts = 0; t->auth_key = auth_key; adbd_notify_framework_connected_key(t); } else { } else { if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s); if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s); send_auth_request(t); send_auth_request(t); Loading @@ -348,7 +351,8 @@ void handle_packet(apacket *p, atransport *t) } } case ADB_AUTH_RSAPUBLICKEY: case ADB_AUTH_RSAPUBLICKEY: adbd_auth_confirm_key(p->payload.data(), p->msg.data_length, t); t->auth_key = std::string(p->payload.data()); adbd_auth_confirm_key(t); break; break; #endif #endif default: default: Loading adb/adb.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024; constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024; constexpr size_t MAX_PAYLOAD = 1024 * 1024; constexpr size_t MAX_PAYLOAD = 1024 * 1024; constexpr size_t MAX_FRAMEWORK_PAYLOAD = 64 * 1024; constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304; constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304; Loading adb/adb_auth.h +4 −2 Original line number Original line Diff line number Diff line Loading @@ -50,8 +50,10 @@ void adbd_auth_init(void); void adbd_auth_verified(atransport *t); void adbd_auth_verified(atransport *t); void adbd_cloexec_auth_socket(); void adbd_cloexec_auth_socket(); bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig); bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig, void adbd_auth_confirm_key(const char* data, size_t len, atransport* t); std::string* auth_key); void adbd_auth_confirm_key(atransport* t); void adbd_notify_framework_connected_key(atransport* t); void send_auth_request(atransport *t); void send_auth_request(atransport *t); Loading adb/daemon/auth.cpp +101 −47 Original line number Original line Diff line number Diff line Loading @@ -26,7 +26,9 @@ #include <resolv.h> #include <resolv.h> #include <stdio.h> #include <stdio.h> #include <string.h> #include <string.h> #include <iomanip> #include <algorithm> #include <memory> #include <memory> #include <android-base/file.h> #include <android-base/file.h> Loading @@ -38,22 +40,24 @@ static fdevent* listener_fde = nullptr; static fdevent* listener_fde = nullptr; static fdevent* framework_fde = nullptr; static fdevent* framework_fde = nullptr; static int framework_fd = -1; static auto& framework_mutex = *new std::mutex(); static int framework_fd GUARDED_BY(framework_mutex) = -1; static auto& connected_keys GUARDED_BY(framework_mutex) = *new std::vector<std::string>; static void usb_disconnected(void* unused, atransport* t); static void adb_disconnected(void* unused, atransport* t); static struct adisconnect usb_disconnect = { usb_disconnected, nullptr}; static struct adisconnect adb_disconnect = {adb_disconnected, nullptr}; static atransport* usb_transport; static atransport* adb_transport; static bool needs_retry = false; static bool needs_retry = false; bool auth_required = true; bool auth_required = true; bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig) { bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig, std::string* auth_key) { static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr }; static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr }; for (const auto& path : key_paths) { for (const auto& path : key_paths) { if (access(path, R_OK) == 0) { if (access(path, R_OK) == 0) { LOG(INFO) << "Loading keys from " << path; LOG(INFO) << "Loading keys from " << path; std::string content; std::string content; if (!android::base::ReadFileToString(path, &content)) { if (!android::base::ReadFileToString(path, &content)) { PLOG(ERROR) << "Couldn't read " << path; PLOG(ERROR) << "Couldn't read " << path; Loading @@ -61,6 +65,8 @@ bool adbd_auth_verify(const char* token, size_t token_size, const std::string& s } } for (const auto& line : android::base::Split(content, "\n")) { for (const auto& line : android::base::Split(content, "\n")) { if (line.empty()) continue; *auth_key = line; // TODO: do we really have to support both ' ' and '\t'? // TODO: do we really have to support both ' ' and '\t'? char* sep = strpbrk(const_cast<char*>(line.c_str()), " \t"); char* sep = strpbrk(const_cast<char*>(line.c_str()), " \t"); if (sep) *sep = '\0'; if (sep) *sep = '\0'; Loading Loading @@ -88,9 +94,31 @@ bool adbd_auth_verify(const char* token, size_t token_size, const std::string& s } } } } } } auth_key->clear(); return false; } static bool adbd_send_key_message_locked(std::string_view msg_type, std::string_view key) REQUIRES(framework_mutex) { if (framework_fd < 0) { LOG(ERROR) << "Client not connected to send msg_type " << msg_type; return false; } std::string msg = std::string(msg_type) + std::string(key); int msg_len = msg.length(); if (msg_len >= static_cast<int>(MAX_FRAMEWORK_PAYLOAD)) { LOG(ERROR) << "Key too long (" << msg_len << ")"; return false; return false; } } LOG(DEBUG) << "Sending '" << msg << "'"; if (!WriteFdExactly(framework_fd, msg.c_str(), msg_len)) { PLOG(ERROR) << "Failed to write " << msg_type; return false; } return true; } static bool adbd_auth_generate_token(void* token, size_t token_size) { static bool adbd_auth_generate_token(void* token, size_t token_size) { FILE* fp = fopen("/dev/urandom", "re"); FILE* fp = fopen("/dev/urandom", "re"); if (!fp) return false; if (!fp) return false; Loading @@ -99,19 +127,30 @@ static bool adbd_auth_generate_token(void* token, size_t token_size) { return okay; return okay; } } static void usb_disconnected(void* unused, atransport* t) { static void adb_disconnected(void* unused, atransport* t) { LOG(INFO) << "USB disconnect"; LOG(INFO) << "ADB disconnect"; usb_transport = nullptr; adb_transport = nullptr; needs_retry = false; needs_retry = false; { std::lock_guard<std::mutex> lock(framework_mutex); if (framework_fd >= 0) { adbd_send_key_message_locked("DC", t->auth_key); } connected_keys.erase(std::remove(connected_keys.begin(), connected_keys.end(), t->auth_key), connected_keys.end()); } } } static void framework_disconnected() { static void framework_disconnected() { LOG(INFO) << "Framework disconnect"; LOG(INFO) << "Framework disconnect"; if (framework_fde) { if (framework_fde) { fdevent_destroy(framework_fde); fdevent_destroy(framework_fde); { std::lock_guard<std::mutex> lock(framework_mutex); framework_fd = -1; framework_fd = -1; } } } } } static void adbd_auth_event(int fd, unsigned events, void*) { static void adbd_auth_event(int fd, unsigned events, void*) { if (events & FDE_READ) { if (events & FDE_READ) { Loading @@ -120,41 +159,28 @@ static void adbd_auth_event(int fd, unsigned events, void*) { if (ret <= 0) { if (ret <= 0) { framework_disconnected(); framework_disconnected(); } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { if (usb_transport) { if (adb_transport) { adbd_auth_verified(usb_transport); adbd_auth_verified(adb_transport); } } } } } } } } void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) { void adbd_auth_confirm_key(atransport* t) { if (!usb_transport) { if (!adb_transport) { usb_transport = t; adb_transport = t; t->AddDisconnect(&usb_disconnect); t->AddDisconnect(&adb_disconnect); } } { std::lock_guard<std::mutex> lock(framework_mutex); if (framework_fd < 0) { if (framework_fd < 0) { LOG(ERROR) << "Client not connected"; LOG(ERROR) << "Client not connected"; needs_retry = true; needs_retry = true; return; return; } } if (key[len - 1] != '\0') { adbd_send_key_message_locked("PK", t->auth_key); LOG(ERROR) << "Key must be a null-terminated string"; return; } char msg[MAX_PAYLOAD_V1]; int msg_len = snprintf(msg, sizeof(msg), "PK%s", key); if (msg_len >= static_cast<int>(sizeof(msg))) { LOG(ERROR) << "Key too long (" << msg_len << ")"; return; } LOG(DEBUG) << "Sending '" << msg << "'"; if (unix_write(framework_fd, msg, msg_len) == -1) { PLOG(ERROR) << "Failed to write PK"; return; } } } } Loading @@ -165,6 +191,8 @@ static void adbd_auth_listener(int fd, unsigned events, void* data) { return; return; } } { std::lock_guard<std::mutex> lock(framework_mutex); if (framework_fd >= 0) { if (framework_fd >= 0) { LOG(WARNING) << "adb received framework auth socket connection again"; LOG(WARNING) << "adb received framework auth socket connection again"; framework_disconnected(); framework_disconnected(); Loading @@ -176,7 +204,33 @@ static void adbd_auth_listener(int fd, unsigned events, void* data) { if (needs_retry) { if (needs_retry) { needs_retry = false; needs_retry = false; send_auth_request(usb_transport); send_auth_request(adb_transport); } // if a client connected before the framework was available notify the framework of the // connected key now. if (!connected_keys.empty()) { for (const auto& key : connected_keys) { adbd_send_key_message_locked("CK", key); } } } } void adbd_notify_framework_connected_key(atransport* t) { if (!adb_transport) { adb_transport = t; t->AddDisconnect(&adb_disconnect); } { std::lock_guard<std::mutex> lock(framework_mutex); if (std::find(connected_keys.begin(), connected_keys.end(), t->auth_key) == connected_keys.end()) { connected_keys.push_back(t->auth_key); } if (framework_fd >= 0) { adbd_send_key_message_locked("CK", t->auth_key); } } } } } Loading adb/daemon/usb.cpp +7 −20 Original line number Original line Diff line number Diff line Loading @@ -509,16 +509,14 @@ struct UsbFfsConnection : public Connection { } } if (id.direction == TransferDirection::READ) { if (id.direction == TransferDirection::READ) { if (!HandleRead(id, event.res)) { HandleRead(id, event.res); return; } } else { } else { HandleWrite(id); HandleWrite(id); } } } } } } bool HandleRead(TransferId id, int64_t size) { void HandleRead(TransferId id, int64_t size) { uint64_t read_idx = id.id % kUsbReadQueueDepth; uint64_t read_idx = id.id % kUsbReadQueueDepth; IoBlock* block = &read_requests_[read_idx]; IoBlock* block = &read_requests_[read_idx]; block->pending = false; block->pending = false; Loading @@ -528,7 +526,7 @@ struct UsbFfsConnection : public Connection { if (block->id().id != needed_read_id_) { if (block->id().id != needed_read_id_) { LOG(VERBOSE) << "read " << block->id().id << " completed while waiting for " LOG(VERBOSE) << "read " << block->id().id << " completed while waiting for " << needed_read_id_; << needed_read_id_; return true; return; } } for (uint64_t id = needed_read_id_;; ++id) { for (uint64_t id = needed_read_id_;; ++id) { Loading @@ -537,22 +535,15 @@ struct UsbFfsConnection : public Connection { if (current_block->pending) { if (current_block->pending) { break; break; } } if (!ProcessRead(current_block)) { ProcessRead(current_block); return false; } ++needed_read_id_; ++needed_read_id_; } } return true; } } bool ProcessRead(IoBlock* block) { void ProcessRead(IoBlock* block) { if (!block->payload->empty()) { if (!block->payload->empty()) { if (!incoming_header_.has_value()) { if (!incoming_header_.has_value()) { if (block->payload->size() != sizeof(amessage)) { CHECK_EQ(sizeof(amessage), block->payload->size()); HandleError("received packet of unexpected length while reading header"); return false; } amessage msg; amessage msg; memcpy(&msg, block->payload->data(), sizeof(amessage)); memcpy(&msg, block->payload->data(), sizeof(amessage)); LOG(DEBUG) << "USB read:" << dump_header(&msg); LOG(DEBUG) << "USB read:" << dump_header(&msg); Loading @@ -560,10 +551,7 @@ struct UsbFfsConnection : public Connection { } else { } else { size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); Block payload = std::move(*block->payload); Block payload = std::move(*block->payload); if (block->payload->size() > bytes_left) { CHECK_LE(payload.size(), bytes_left); HandleError("received too many bytes while waiting for payload"); return false; } incoming_payload_.append(std::make_unique<Block>(std::move(payload))); incoming_payload_.append(std::make_unique<Block>(std::move(payload))); } } Loading @@ -582,7 +570,6 @@ struct UsbFfsConnection : public Connection { PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth); PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth); SubmitRead(block); SubmitRead(block); return true; } } bool SubmitRead(IoBlock* block) { bool SubmitRead(IoBlock* block) { Loading Loading
adb/adb.cpp +6 −2 Original line number Original line Diff line number Diff line Loading @@ -337,9 +337,12 @@ void handle_packet(apacket *p, atransport *t) case ADB_AUTH_SIGNATURE: { case ADB_AUTH_SIGNATURE: { // TODO: Switch to string_view. // TODO: Switch to string_view. std::string signature(p->payload.begin(), p->payload.end()); std::string signature(p->payload.begin(), p->payload.end()); if (adbd_auth_verify(t->token, sizeof(t->token), signature)) { std::string auth_key; if (adbd_auth_verify(t->token, sizeof(t->token), signature, &auth_key)) { adbd_auth_verified(t); adbd_auth_verified(t); t->failed_auth_attempts = 0; t->failed_auth_attempts = 0; t->auth_key = auth_key; adbd_notify_framework_connected_key(t); } else { } else { if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s); if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s); send_auth_request(t); send_auth_request(t); Loading @@ -348,7 +351,8 @@ void handle_packet(apacket *p, atransport *t) } } case ADB_AUTH_RSAPUBLICKEY: case ADB_AUTH_RSAPUBLICKEY: adbd_auth_confirm_key(p->payload.data(), p->msg.data_length, t); t->auth_key = std::string(p->payload.data()); adbd_auth_confirm_key(t); break; break; #endif #endif default: default: Loading
adb/adb.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024; constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024; constexpr size_t MAX_PAYLOAD = 1024 * 1024; constexpr size_t MAX_PAYLOAD = 1024 * 1024; constexpr size_t MAX_FRAMEWORK_PAYLOAD = 64 * 1024; constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304; constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304; Loading
adb/adb_auth.h +4 −2 Original line number Original line Diff line number Diff line Loading @@ -50,8 +50,10 @@ void adbd_auth_init(void); void adbd_auth_verified(atransport *t); void adbd_auth_verified(atransport *t); void adbd_cloexec_auth_socket(); void adbd_cloexec_auth_socket(); bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig); bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig, void adbd_auth_confirm_key(const char* data, size_t len, atransport* t); std::string* auth_key); void adbd_auth_confirm_key(atransport* t); void adbd_notify_framework_connected_key(atransport* t); void send_auth_request(atransport *t); void send_auth_request(atransport *t); Loading
adb/daemon/auth.cpp +101 −47 Original line number Original line Diff line number Diff line Loading @@ -26,7 +26,9 @@ #include <resolv.h> #include <resolv.h> #include <stdio.h> #include <stdio.h> #include <string.h> #include <string.h> #include <iomanip> #include <algorithm> #include <memory> #include <memory> #include <android-base/file.h> #include <android-base/file.h> Loading @@ -38,22 +40,24 @@ static fdevent* listener_fde = nullptr; static fdevent* listener_fde = nullptr; static fdevent* framework_fde = nullptr; static fdevent* framework_fde = nullptr; static int framework_fd = -1; static auto& framework_mutex = *new std::mutex(); static int framework_fd GUARDED_BY(framework_mutex) = -1; static auto& connected_keys GUARDED_BY(framework_mutex) = *new std::vector<std::string>; static void usb_disconnected(void* unused, atransport* t); static void adb_disconnected(void* unused, atransport* t); static struct adisconnect usb_disconnect = { usb_disconnected, nullptr}; static struct adisconnect adb_disconnect = {adb_disconnected, nullptr}; static atransport* usb_transport; static atransport* adb_transport; static bool needs_retry = false; static bool needs_retry = false; bool auth_required = true; bool auth_required = true; bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig) { bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig, std::string* auth_key) { static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr }; static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr }; for (const auto& path : key_paths) { for (const auto& path : key_paths) { if (access(path, R_OK) == 0) { if (access(path, R_OK) == 0) { LOG(INFO) << "Loading keys from " << path; LOG(INFO) << "Loading keys from " << path; std::string content; std::string content; if (!android::base::ReadFileToString(path, &content)) { if (!android::base::ReadFileToString(path, &content)) { PLOG(ERROR) << "Couldn't read " << path; PLOG(ERROR) << "Couldn't read " << path; Loading @@ -61,6 +65,8 @@ bool adbd_auth_verify(const char* token, size_t token_size, const std::string& s } } for (const auto& line : android::base::Split(content, "\n")) { for (const auto& line : android::base::Split(content, "\n")) { if (line.empty()) continue; *auth_key = line; // TODO: do we really have to support both ' ' and '\t'? // TODO: do we really have to support both ' ' and '\t'? char* sep = strpbrk(const_cast<char*>(line.c_str()), " \t"); char* sep = strpbrk(const_cast<char*>(line.c_str()), " \t"); if (sep) *sep = '\0'; if (sep) *sep = '\0'; Loading Loading @@ -88,9 +94,31 @@ bool adbd_auth_verify(const char* token, size_t token_size, const std::string& s } } } } } } auth_key->clear(); return false; } static bool adbd_send_key_message_locked(std::string_view msg_type, std::string_view key) REQUIRES(framework_mutex) { if (framework_fd < 0) { LOG(ERROR) << "Client not connected to send msg_type " << msg_type; return false; } std::string msg = std::string(msg_type) + std::string(key); int msg_len = msg.length(); if (msg_len >= static_cast<int>(MAX_FRAMEWORK_PAYLOAD)) { LOG(ERROR) << "Key too long (" << msg_len << ")"; return false; return false; } } LOG(DEBUG) << "Sending '" << msg << "'"; if (!WriteFdExactly(framework_fd, msg.c_str(), msg_len)) { PLOG(ERROR) << "Failed to write " << msg_type; return false; } return true; } static bool adbd_auth_generate_token(void* token, size_t token_size) { static bool adbd_auth_generate_token(void* token, size_t token_size) { FILE* fp = fopen("/dev/urandom", "re"); FILE* fp = fopen("/dev/urandom", "re"); if (!fp) return false; if (!fp) return false; Loading @@ -99,19 +127,30 @@ static bool adbd_auth_generate_token(void* token, size_t token_size) { return okay; return okay; } } static void usb_disconnected(void* unused, atransport* t) { static void adb_disconnected(void* unused, atransport* t) { LOG(INFO) << "USB disconnect"; LOG(INFO) << "ADB disconnect"; usb_transport = nullptr; adb_transport = nullptr; needs_retry = false; needs_retry = false; { std::lock_guard<std::mutex> lock(framework_mutex); if (framework_fd >= 0) { adbd_send_key_message_locked("DC", t->auth_key); } connected_keys.erase(std::remove(connected_keys.begin(), connected_keys.end(), t->auth_key), connected_keys.end()); } } } static void framework_disconnected() { static void framework_disconnected() { LOG(INFO) << "Framework disconnect"; LOG(INFO) << "Framework disconnect"; if (framework_fde) { if (framework_fde) { fdevent_destroy(framework_fde); fdevent_destroy(framework_fde); { std::lock_guard<std::mutex> lock(framework_mutex); framework_fd = -1; framework_fd = -1; } } } } } static void adbd_auth_event(int fd, unsigned events, void*) { static void adbd_auth_event(int fd, unsigned events, void*) { if (events & FDE_READ) { if (events & FDE_READ) { Loading @@ -120,41 +159,28 @@ static void adbd_auth_event(int fd, unsigned events, void*) { if (ret <= 0) { if (ret <= 0) { framework_disconnected(); framework_disconnected(); } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { if (usb_transport) { if (adb_transport) { adbd_auth_verified(usb_transport); adbd_auth_verified(adb_transport); } } } } } } } } void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) { void adbd_auth_confirm_key(atransport* t) { if (!usb_transport) { if (!adb_transport) { usb_transport = t; adb_transport = t; t->AddDisconnect(&usb_disconnect); t->AddDisconnect(&adb_disconnect); } } { std::lock_guard<std::mutex> lock(framework_mutex); if (framework_fd < 0) { if (framework_fd < 0) { LOG(ERROR) << "Client not connected"; LOG(ERROR) << "Client not connected"; needs_retry = true; needs_retry = true; return; return; } } if (key[len - 1] != '\0') { adbd_send_key_message_locked("PK", t->auth_key); LOG(ERROR) << "Key must be a null-terminated string"; return; } char msg[MAX_PAYLOAD_V1]; int msg_len = snprintf(msg, sizeof(msg), "PK%s", key); if (msg_len >= static_cast<int>(sizeof(msg))) { LOG(ERROR) << "Key too long (" << msg_len << ")"; return; } LOG(DEBUG) << "Sending '" << msg << "'"; if (unix_write(framework_fd, msg, msg_len) == -1) { PLOG(ERROR) << "Failed to write PK"; return; } } } } Loading @@ -165,6 +191,8 @@ static void adbd_auth_listener(int fd, unsigned events, void* data) { return; return; } } { std::lock_guard<std::mutex> lock(framework_mutex); if (framework_fd >= 0) { if (framework_fd >= 0) { LOG(WARNING) << "adb received framework auth socket connection again"; LOG(WARNING) << "adb received framework auth socket connection again"; framework_disconnected(); framework_disconnected(); Loading @@ -176,7 +204,33 @@ static void adbd_auth_listener(int fd, unsigned events, void* data) { if (needs_retry) { if (needs_retry) { needs_retry = false; needs_retry = false; send_auth_request(usb_transport); send_auth_request(adb_transport); } // if a client connected before the framework was available notify the framework of the // connected key now. if (!connected_keys.empty()) { for (const auto& key : connected_keys) { adbd_send_key_message_locked("CK", key); } } } } void adbd_notify_framework_connected_key(atransport* t) { if (!adb_transport) { adb_transport = t; t->AddDisconnect(&adb_disconnect); } { std::lock_guard<std::mutex> lock(framework_mutex); if (std::find(connected_keys.begin(), connected_keys.end(), t->auth_key) == connected_keys.end()) { connected_keys.push_back(t->auth_key); } if (framework_fd >= 0) { adbd_send_key_message_locked("CK", t->auth_key); } } } } } Loading
adb/daemon/usb.cpp +7 −20 Original line number Original line Diff line number Diff line Loading @@ -509,16 +509,14 @@ struct UsbFfsConnection : public Connection { } } if (id.direction == TransferDirection::READ) { if (id.direction == TransferDirection::READ) { if (!HandleRead(id, event.res)) { HandleRead(id, event.res); return; } } else { } else { HandleWrite(id); HandleWrite(id); } } } } } } bool HandleRead(TransferId id, int64_t size) { void HandleRead(TransferId id, int64_t size) { uint64_t read_idx = id.id % kUsbReadQueueDepth; uint64_t read_idx = id.id % kUsbReadQueueDepth; IoBlock* block = &read_requests_[read_idx]; IoBlock* block = &read_requests_[read_idx]; block->pending = false; block->pending = false; Loading @@ -528,7 +526,7 @@ struct UsbFfsConnection : public Connection { if (block->id().id != needed_read_id_) { if (block->id().id != needed_read_id_) { LOG(VERBOSE) << "read " << block->id().id << " completed while waiting for " LOG(VERBOSE) << "read " << block->id().id << " completed while waiting for " << needed_read_id_; << needed_read_id_; return true; return; } } for (uint64_t id = needed_read_id_;; ++id) { for (uint64_t id = needed_read_id_;; ++id) { Loading @@ -537,22 +535,15 @@ struct UsbFfsConnection : public Connection { if (current_block->pending) { if (current_block->pending) { break; break; } } if (!ProcessRead(current_block)) { ProcessRead(current_block); return false; } ++needed_read_id_; ++needed_read_id_; } } return true; } } bool ProcessRead(IoBlock* block) { void ProcessRead(IoBlock* block) { if (!block->payload->empty()) { if (!block->payload->empty()) { if (!incoming_header_.has_value()) { if (!incoming_header_.has_value()) { if (block->payload->size() != sizeof(amessage)) { CHECK_EQ(sizeof(amessage), block->payload->size()); HandleError("received packet of unexpected length while reading header"); return false; } amessage msg; amessage msg; memcpy(&msg, block->payload->data(), sizeof(amessage)); memcpy(&msg, block->payload->data(), sizeof(amessage)); LOG(DEBUG) << "USB read:" << dump_header(&msg); LOG(DEBUG) << "USB read:" << dump_header(&msg); Loading @@ -560,10 +551,7 @@ struct UsbFfsConnection : public Connection { } else { } else { size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); Block payload = std::move(*block->payload); Block payload = std::move(*block->payload); if (block->payload->size() > bytes_left) { CHECK_LE(payload.size(), bytes_left); HandleError("received too many bytes while waiting for payload"); return false; } incoming_payload_.append(std::make_unique<Block>(std::move(payload))); incoming_payload_.append(std::make_unique<Block>(std::move(payload))); } } Loading @@ -582,7 +570,6 @@ struct UsbFfsConnection : public Connection { PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth); PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth); SubmitRead(block); SubmitRead(block); return true; } } bool SubmitRead(IoBlock* block) { bool SubmitRead(IoBlock* block) { Loading