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

Commit f1a58f8f authored by Elliott Hughes's avatar Elliott Hughes
Browse files

More fixed-length buffer removal.

Bug: http://b/20666660
Change-Id: I0c738e9fed2defed48a9cf2d0a4f7b99c08dcf3d
(cherry picked from commit 6452a89a)
parent 01565898
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -243,8 +243,6 @@ void install_local_socket(asocket *s);
void remove_socket(asocket *s);
void close_all_sockets(atransport *t);

#define  LOCAL_CLIENT_PREFIX  "emulator-"

asocket *create_local_socket(int fd);
asocket *create_local_service_socket(const char *destination);

+81 −112
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <vector>

#include <base/stringprintf.h>
#include <base/strings.h>

#include "adb_io.h"

@@ -41,6 +42,29 @@ static const char* __adb_serial = NULL;
static int __adb_server_port = DEFAULT_ADB_PORT;
static const char* __adb_server_name = NULL;

static std::string perror_str(const char* msg) {
    return android::base::StringPrintf("%s: %s", msg, strerror(errno));
}

static bool ReadProtocolString(int fd, std::string* s, std::string* error) {
    char buf[5];

    if (!ReadFdExactly(fd, buf, 4)) {
        *error = perror_str("protocol fault (couldn't read status length)");
        return false;
    }
    buf[4] = 0;

    unsigned long len = strtoul(buf, 0, 16);
    s->resize(len + 1, '\0'); // Ensure NUL-termination.
    if (!ReadFdExactly(fd, &(*s)[0], len)) {
        *error = perror_str("protocol fault (couldn't read status message)");
        return false;
    }

    return true;
}

void adb_set_transport(transport_type type, const char* serial)
{
    __adb_transport = type;
@@ -57,58 +81,36 @@ void adb_set_tcp_name(const char* hostname)
    __adb_server_name = hostname;
}

int  adb_get_emulator_console_port(void)
{
    const char*   serial = __adb_serial;
int adb_get_emulator_console_port() {
    if (__adb_serial) {
        // The user specified a serial number; is it an emulator?
        int port;
        return (sscanf(__adb_serial, "emulator-%d", &port) == 1) ? port : -1;
    }

    if (serial == NULL) {
        /* if no specific device was specified, we need to look at */
        /* the list of connected devices, and extract an emulator  */
        /* name from it. two emulators is an error                 */
    // No specific device was given, so get the list of connected
    // devices and search for emulators. If there's one, we'll
    // take it. If there are more than one, that's an error.
    std::string devices;
    std::string error;
        char*  tmp = adb_query("host:devices", &error);
        char*  p   = tmp;
        if (!tmp) {
    if (!adb_query("host:devices", &devices, &error)) {
        printf("no emulator connected: %s\n", error.c_str());
        return -1;
    }
        while (*p) {
            char*  q = strchr(p, '\n');
            if (q != NULL)
                *q++ = 0;
            else
                q = p + strlen(p);

            if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
                if (serial != NULL) {  /* more than one emulator listed */
                    free(tmp);
    int port;
    size_t emulator_count = 0;
    for (auto& device : android::base::Split(devices, "\n")) {
        if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
            if (++emulator_count > 1) {
                return -2;
            }
                serial = p;
            }

            p = q;
        }
        free(tmp);

        if (serial == NULL)
            return -1;  /* no emulator found */
        }
    else {
        if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
            return -1;  /* not an emulator */
    }

    serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
    port    = strtol(serial, NULL, 10);
    if (emulator_count == 0) return -1;
    return port;
}

std::string perror_str(const char* msg) {
    return android::base::StringPrintf("%s: %s", msg, strerror(errno));
}

static int switch_socket_transport(int fd, std::string* error) {
    std::string service;
    if (__adb_serial) {
@@ -170,47 +172,36 @@ bool adb_status(int fd, std::string* error) {
        return false;
    }

    if (!ReadFdExactly(fd, buf, 4)) {
        *error = perror_str("protocol fault (couldn't read status length)");
        return false;
    }
    buf[4] = 0;

    unsigned long len = strtoul(buf, 0, 16);
    error->resize(len + 1, '\0'); // Ensure NUL-termination.
    if (!ReadFdExactly(fd, &(*error)[0], len)) {
        *error = perror_str("protocol fault (couldn't read status message)");
    }
    ReadProtocolString(fd, error, error);
    return false;
}

int _adb_connect(const char *service, std::string* error) {
    char tmp[5];
    int fd;

    D("_adb_connect: %s\n", service);
    size_t len = strlen(service);
    if ((len < 1) || (len > 1024)) {
        *error = android::base::StringPrintf("service name too long (%d)", static_cast<int>(len));
int _adb_connect(const std::string& service, std::string* error) {
    D("_adb_connect: %s\n", service.c_str());
    if (service.empty() || service.size() > 1024) {
        *error = android::base::StringPrintf("bad service name length (%d)",
                                             static_cast<int>(service.size()));
        return -1;
    }
    snprintf(tmp, sizeof tmp, "%04zx", len);

    if (__adb_server_name)
    int fd;
    if (__adb_server_name) {
        fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
    else
    } else {
        fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);

    }
    if (fd < 0) {
        *error = perror_str("cannot connect to daemon");
        return -2;
    }

    if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd, error)) {
    if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
        return -1;
    }

    if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
    char tmp[5];
    snprintf(tmp, sizeof(tmp), "%04zx", service.size());
    if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, &service[0], service.size())) {
        *error = perror_str("write failure during connection");
        adb_close(fd);
        return -1;
@@ -225,11 +216,11 @@ int _adb_connect(const char *service, std::string* error) {
    return fd;
}

int adb_connect(const char* service, std::string* error) {
int adb_connect(const std::string& service, std::string* error) {
    // first query the adb server's version
    int fd = _adb_connect("host:version", error);

    D("adb_connect: service %s\n", service);
    D("adb_connect: service %s\n", service.c_str());
    if (fd == -2 && __adb_server_name) {
        fprintf(stderr,"** Cannot start server on remote host\n");
        return fd;
@@ -248,21 +239,20 @@ int adb_connect(const char* service, std::string* error) {
        // fall through to _adb_connect
    } else {
        // if server was running, check its version to make sure it is not out of date
        char buf[100];
        size_t n;
        int version = ADB_SERVER_VERSION - 1;

        // if we have a file descriptor, then parse version result
        if (fd >= 0) {
            if(!ReadFdExactly(fd, buf, 4)) goto error;
            std::string version_string;
            if (!ReadProtocolString(fd, &version_string, error)) {
                goto error;
            }

            buf[4] = 0;
            n = strtoul(buf, 0, 16);
            if(n > sizeof(buf)) goto error;
            if(!ReadFdExactly(fd, buf, n)) goto error;
            adb_close(fd);

            if (sscanf(buf, "%04x", &version) != 1) goto error;
            if (sscanf(&version_string[0], "%04x", &version) != 1) {
                goto error;
            }
        } else {
            // if fd is -1, then check for "unknown host service",
            // which would indicate a version of adb that does not support the version command
@@ -283,7 +273,7 @@ int adb_connect(const char* service, std::string* error) {
    }

    // if the command is start-server, we are done.
    if (!strcmp(service, "host:start-server")) {
    if (service == "host:start-server") {
        return 0;
    }

@@ -302,7 +292,7 @@ error:
}


int adb_command(const char* service, std::string* error) {
int adb_command(const std::string& service, std::string* error) {
    int fd = adb_connect(service, error);
    if (fd < 0) {
        fprintf(stderr, "error: %s\n", error->c_str());
@@ -317,39 +307,18 @@ int adb_command(const char* service, std::string* error) {
    return 0;
}

char* adb_query(const char* service, std::string* error) {
    char buf[5];
    unsigned long n;
    char* tmp;

    D("adb_query: %s\n", service);
bool adb_query(const std::string& service, std::string* result, std::string* error) {
    D("adb_query: %s\n", service.c_str());
    int fd = adb_connect(service, error);
    if (fd < 0) {
        fprintf(stderr,"error: %s\n", error->c_str());
        return 0;
    }

    if (!ReadFdExactly(fd, buf, 4)) goto oops;

    buf[4] = 0;
    n = strtoul(buf, 0, 16);
    // TODO: given that we just read a 4-byte hex length 0x????, why the test?
    if (n >= 0xffff) {
        *error = "reply is too long (>= 64KiB)";
        goto oops;
    }

    tmp = reinterpret_cast<char*>(malloc(n + 1));
    if(tmp == 0) goto oops;

    if(!ReadFdExactly(fd, tmp, n) == 0) {
        tmp[n] = 0;
    result->clear();
    if (!ReadProtocolString(fd, result, error)) {
        adb_close(fd);
        return tmp;
        return false;
    }
    free(tmp);

oops:
    adb_close(fd);
    return 0;
    return true;
}
+6 −8
Original line number Diff line number Diff line
@@ -9,19 +9,17 @@
** a valid fd for interacting with that service upon success
** or a negative number on failure
*/
int adb_connect(const char* service, std::string* error);
int _adb_connect(const char* service, std::string* error);
int adb_connect(const std::string& service, std::string* error);
int _adb_connect(const std::string& service, std::string* error);

/* connect to adb, connect to the named service, return 0 if
** the connection succeeded AND the service returned OKAY
*/
int adb_command(const char* service, std::string* error);
int adb_command(const std::string& service, std::string* error);

/* connect to adb, connect to the named service, return
** a malloc'd string of its response upon success or NULL
** on failure.
*/
char* adb_query(const char* service, std::string* error);
// Connects to the named adb service and fills 'result' with the response.
// Returns true on success; returns false and fills 'error' on failure.
bool adb_query(const std::string& service, std::string* result, std::string* error);

/* Set the preferred transport to connect to.
*/
+64 −148
Original line number Diff line number Diff line
@@ -201,7 +201,6 @@ static void help() {
        "  adb get-state                - prints: offline | bootloader | device\n"
        "  adb get-serialno             - prints: <serial-number>\n"
        "  adb get-devpath              - prints: <device-path>\n"
        "  adb status-window            - continuously print device status for a specified device\n"
        "  adb remount                  - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write\n"
        "  adb reboot [bootloader|recovery]\n"
        "                               - reboots the device, optionally into the bootloader or recovery program.\n"
@@ -437,31 +436,25 @@ static int interactive_shell() {
}


static void format_host_command(char* buffer, size_t  buflen, const char* command, transport_type ttype, const char* serial)
{
static std::string format_host_command(const char* command, transport_type type, const char* serial) {
    if (serial) {
        snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
    } else {
        return android::base::StringPrintf("host-serial:%s:%s", serial, command);
    }

    const char* prefix = "host";
        if (ttype == kTransportUsb)
    if (type == kTransportUsb) {
        prefix = "host-usb";
        else if (ttype == kTransportLocal)
    } else if (type == kTransportLocal) {
        prefix = "host-local";

        snprintf(buffer, buflen, "%s:%s", prefix, command);
    }
    return android::base::StringPrintf("%s:%s", prefix, command);
}

static int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
                               bool show_progress)
{
    char buf[4096];
    unsigned total;

    sprintf(buf,"%s:%d", service, sz);

    std::string error;
    int fd = adb_connect(buf, &error);
    int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
    if (fd < 0) {
        fprintf(stderr,"error: %s\n", error.c_str());
        return -1;
@@ -470,7 +463,7 @@ static int adb_download_buffer(const char *service, const char *fn, const void*
    int opt = CHUNK_SIZE;
    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));

    total = sz;
    unsigned total = sz;
    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);

    if (show_progress) {
@@ -497,6 +490,8 @@ static int adb_download_buffer(const char *service, const char *fn, const void*
        printf("\n");
    }

    // TODO: should this be adb_status?
    char buf[5];
    if(!ReadFdExactly(fd, buf, 4)){
        fprintf(stderr,"* error reading response *\n");
        adb_close(fd);
@@ -550,10 +545,10 @@ static int adb_sideload_host(const char* fn) {
        return -1;
    }

    char buf[100];
    sprintf(buf, "sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
    std::string service =
            android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
    std::string error;
    int fd = adb_connect(buf, &error);
    int fd = adb_connect(service, &error);
    if (fd < 0) {
        // Try falling back to the older sideload method.  Maybe this
        // is an older device that doesn't support sideload-host.
@@ -565,18 +560,19 @@ static int adb_sideload_host(const char* fn) {
    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));

    while (true) {
        char buf[9];
        if (!ReadFdExactly(fd, buf, 8)) {
            fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
            status = -1;
            goto done;
        }
        buf[8] = '\0';

        if (strncmp("DONEDONE", buf, 8) == 0) {
        if (strcmp("DONEDONE", buf) == 0) {
            status = 0;
            break;
        }

        buf[8] = '\0';
        int block = strtol(buf, NULL, 10);

        size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
@@ -622,51 +618,6 @@ static int adb_sideload_host(const char* fn) {
    return status;
}

static void status_window(transport_type ttype, const char* serial)
{
    char command[4096];
    char *state = 0;
    char *laststate = 0;

        /* silence stderr */
#ifdef _WIN32
    /* XXX: TODO */
#else
    int  fd;
    fd = unix_open("/dev/null", O_WRONLY);
    dup2(fd, 2);
    adb_close(fd);
#endif

    format_host_command(command, sizeof command, "get-state", ttype, serial);

    while (true) {
        adb_sleep_ms(250);

        if (state) {
            free(state);
            state = 0;
        }

        std::string error;
        state = adb_query(command, &error);

        if (state) {
            if (laststate && !strcmp(state,laststate)){
                continue;
            } else {
                if (laststate) free(laststate);
                laststate = strdup(state);
            }
        }

        printf("%c[2J%c[2H", 27, 27);
        printf("Android Debug Bridge\n");
        printf("State: %s\n", state ? state : "offline");
        fflush(stdout);
    }
}

/**
 * Run ppp in "notty" mode against a resource listed as the first parameter
 * eg:
@@ -741,7 +692,7 @@ static int send_shell_command(transport_type transport, const char* serial,
    int fd;
    while (true) {
        std::string error;
        fd = adb_connect(command.c_str(), &error);
        fd = adb_connect(command, &error);
        if (fd >= 0) {
            break;
        }
@@ -835,7 +786,7 @@ static int backup(int argc, const char** argv) {

    D("backup. filename=%s cmd=%s\n", filename, cmd.c_str());
    std::string error;
    int fd = adb_connect(cmd.c_str(), &error);
    int fd = adb_connect(cmd, &error);
    if (fd < 0) {
        fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
        adb_close(outFd);
@@ -964,7 +915,7 @@ static void parse_push_pull_args(const char **arg, int narg, char const **path1,
    }
}

static int adb_connect_command(const char* command) {
static int adb_connect_command(const std::string& command) {
    std::string error;
    int fd = adb_connect(command, &error);
    if (fd != -1) {
@@ -976,6 +927,17 @@ static int adb_connect_command(const char* command) {
    return 1;
}

static int adb_query_command(const std::string& command) {
    std::string result;
    std::string error;
    if (!adb_query(command, &result, &error)) {
        fprintf(stderr, "error: %s\n", error.c_str());
        return 1;
    }
    printf("%s\n", result.c_str());
    return 0;
}

int adb_commandline(int argc, const char **argv)
{
    char buf[4096];
@@ -1129,10 +1091,9 @@ int adb_commandline(int argc, const char **argv)
            }
        }

        format_host_command(buf, sizeof buf, service, ttype, serial);

        std::string cmd = format_host_command(service, ttype, serial);
        std::string error;
        if (adb_command(buf, &error)) {
        if (adb_command(cmd, &error)) {
            D("failure: %s *\n", error.c_str());
            fprintf(stderr,"error: %s\n", error.c_str());
            return 1;
@@ -1152,62 +1113,38 @@ int adb_commandline(int argc, const char **argv)

    /* adb_connect() commands */
    if (!strcmp(argv[0], "devices")) {
        char *tmp;
        const char *listopt;
        if (argc < 2)
        if (argc < 2) {
            listopt = "";
        else if (argc == 2 && !strcmp(argv[1], "-l"))
        } else if (argc == 2 && !strcmp(argv[1], "-l")) {
            listopt = argv[1];
        else {
        } else {
            fprintf(stderr, "Usage: adb devices [-l]\n");
            return 1;
        }
        snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);
        std::string error;
        tmp = adb_query(buf, &error);
        if (tmp) {

        std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
        printf("List of devices attached\n");
            printf("%s\n", tmp);
            return 0;
        } else {
            return 1;
        }
        return adb_query_command(query);
    }
    else if (!strcmp(argv[0], "connect")) {
        char *tmp;
        if (argc != 2) {
            fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
            return 1;
        }
        snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
        std::string error;
        tmp = adb_query(buf, &error);
        if (tmp) {
            printf("%s\n", tmp);
            return 0;
        } else {
            return 1;
        }

        std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
        return adb_query_command(query);
    }
    else if (!strcmp(argv[0], "disconnect")) {
        char *tmp;
        if (argc > 2) {
            fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
            return 1;
        }
        if (argc == 2) {
            snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
        } else {
            snprintf(buf, sizeof buf, "host:disconnect:");
        }
        std::string error;
        tmp = adb_query(buf, &error);
        if (tmp) {
            printf("%s\n", tmp);
            return 0;
        } else {
            return 1;
        }

        std::string query = android::base::StringPrintf("host:disconnect:%s",
                                                        (argc == 2) ? argv[1] : "");
        return adb_query_command(query);
    }
    else if (!strcmp(argv[0], "emu")) {
        return adb_send_emulator_command(argc, argv);
@@ -1241,7 +1178,7 @@ int adb_commandline(int argc, const char **argv)
        while (true) {
            D("interactive shell loop. cmd=%s\n", cmd.c_str());
            std::string error;
            int fd = adb_connect(cmd.c_str(), &error);
            int fd = adb_connect(cmd, &error);
            int r;
            if (fd >= 0) {
                D("about to read_and_dump(fd=%d)\n", fd);
@@ -1280,7 +1217,7 @@ int adb_commandline(int argc, const char **argv)
        }

        std::string error;
        int fd = adb_connect(cmd.c_str(), &error);
        int fd = adb_connect(cmd, &error);
        if (fd < 0) {
            fprintf(stderr, "error: %s\n", error.c_str());
            return -1;
@@ -1385,18 +1322,12 @@ int adb_commandline(int argc, const char **argv)

        // Implement forward --list
        if (list) {
            if (argc != 1)
            if (argc != 1) {
                return usage();
            snprintf(buf, sizeof buf, "%s:list-forward", host_prefix);
            std::string error;
            char* forwards = adb_query(buf, &error);
            if (forwards == NULL) {
                fprintf(stderr, "error: %s\n", error.c_str());
                return 1;
            }
            printf("%s", forwards);
            free(forwards);
            return 0;

            std::string query = android::base::StringPrintf("%s:list-forward", host_prefix);
            return adb_query_command(query);
        }

        // Implement forward --remove-all
@@ -1523,21 +1454,9 @@ int adb_commandline(int argc, const char **argv)
        !strcmp(argv[0],"get-serialno") ||
        !strcmp(argv[0],"get-devpath"))
    {
        format_host_command(buf, sizeof buf, argv[0], ttype, serial);
        std::string error;
        char* tmp = adb_query(buf, &error);
        if (tmp) {
            printf("%s\n", tmp);
            return 0;
        } else {
            return 1;
        }
        return adb_query_command(format_host_command(argv[0], ttype, serial));
    }
    /* other commands */
    else if (!strcmp(argv[0],"status-window")) {
        status_window(ttype, serial);
        return 0;
    }
    else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
        return logcat(ttype, serial, argc, argv);
    }
@@ -1755,7 +1674,7 @@ static int install_multiple_app(transport_type transport, const char* serial, in

    // Create install session
    std::string error;
    int fd = adb_connect(cmd.c_str(), &error);
    int fd = adb_connect(cmd, &error);
    if (fd < 0) {
        fprintf(stderr, "Connect error for create: %s\n", error.c_str());
        return -1;
@@ -1807,7 +1726,7 @@ static int install_multiple_app(transport_type transport, const char* serial, in
        }

        std::string error;
        int remoteFd = adb_connect(cmd.c_str(), &error);
        int remoteFd = adb_connect(cmd, &error);
        if (remoteFd < 0) {
            fprintf(stderr, "Connect error for write: %s\n", error.c_str());
            adb_close(localFd);
@@ -1831,13 +1750,10 @@ static int install_multiple_app(transport_type transport, const char* serial, in

finalize_session:
    // Commit session if we streamed everything okay; otherwise abandon
    if (success) {
        snprintf(buf, sizeof(buf), "exec:pm install-commit %d", session_id);
    } else {
        snprintf(buf, sizeof(buf), "exec:pm install-abandon %d", session_id);
    }

    fd = adb_connect(buf, &error);
    std::string service =
            android::base::StringPrintf("exec:pm install-%s %d",
                                        success ? "commit" : "abandon", session_id);
    fd = adb_connect(service, &error);
    if (fd < 0) {
        fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
        return -1;
+1 −1
Original line number Diff line number Diff line
@@ -847,7 +847,7 @@ retry:
                result = t;
            } else if (ttype == kTransportAny) {
                if (result) {
                    if (error_out) *error_out = "more than one device and emulator";
                    if (error_out) *error_out = "more than one device/emulator";
                    ambiguous = 1;
                    result = NULL;
                    break;
Loading