Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0a45dbc authored by Xin Li's avatar Xin Li Committed by Gerrit Code Review
Browse files

Merge "DO NOT MERGE - Merge Android 10 into master"

parents 915521c7 d4ef92d8
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -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);
@@ -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:
+1 −0
Original line number Original line Diff line number Diff line
@@ -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;


+4 −2
Original line number Original line Diff line number Diff line
@@ -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);


+101 −47
Original line number Original line Diff line number Diff line
@@ -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>
@@ -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;
@@ -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';
@@ -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;
@@ -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) {
@@ -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;
    }
    }
}
}


@@ -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();
@@ -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);
        }
    }
    }
}
}


+7 −20
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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) {
@@ -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);
@@ -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)));
            }
            }


@@ -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