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

Commit ba6d1da8 authored by Josh Gao's avatar Josh Gao
Browse files

adb: add option to disable kill-server.

In the post-apocalypse, it's increasingly common for people to use ssh
port forwarding to use an adb client with a remote adb server. This
results in `adb kill-server` being catastrophic, because the client has
no way of restarting the server on the other end. Android Studio in
particular has an unforunate habit of trying to manage adb's life cycle
such that starting or exiting Studio will result in a kill-server.

Add the ADB_REJECT_KILL_SERVER environment variable which ignores
kill-server, to make this scenario a bit better.

Bug: http://b/152251952
Test: ADB_REJECT_KILL_SERVER=1 adb start-server; adb kill-server
Change-Id: I5533a6dcbdb9220526a6fcf9ca31d9fcef1cec17
parent 362a41a4
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -1071,20 +1071,26 @@ static int SendOkay(int fd, const std::string& s) {
    return 0;
}

static bool g_reject_kill_server = false;
void adb_set_reject_kill_server(bool value) {
    g_reject_kill_server = value;
}

HostRequestResult handle_host_request(std::string_view service, TransportType type,
                                      const char* serial, TransportId transport_id, int reply_fd,
                                      asocket* s) {
    if (service == "kill") {
        if (g_reject_kill_server) {
            LOG(WARNING) << "adb server ignoring kill-server";
            SendFail(reply_fd, "kill-server rejected by remote server");
        } else {
            fprintf(stderr, "adb server killed by remote request\n");
        fflush(stdout);

        // Send a reply even though we don't read it anymore, so that old versions
        // of adb that do read it don't spew error messages.
            SendOkay(reply_fd);

            // Rely on process exit to close the socket for us.
            exit(0);
        }
    }

    LOG(DEBUG) << "handle_host_request(" << service << ")";

+9 −3
Original line number Diff line number Diff line
@@ -14,8 +14,7 @@
 * limitations under the License.
 */

#ifndef __ADB_H
#define __ADB_H
#pragma once

#include <limits.h>
#include <stdint.h>
@@ -237,6 +236,7 @@ void send_tls_request(atransport* t);

void parse_banner(const std::string&, atransport* t);

#if ADB_HOST
// On startup, the adb server needs to wait until all of the connected devices are ready.
// To do this, we need to know when the scan has identified all of the potential new transports, and
// when each transport becomes ready.
@@ -250,6 +250,12 @@ void update_transport_status();

// Wait until device scan has completed and every transport is ready, or a timeout elapses.
void adb_wait_for_device_initialization();
#endif  // ADB_HOST

void usb_init();
#if ADB_HOST
// When ssh-forwarding to a remote adb server, kill-server is almost never what you actually want,
// and unfortunately, many other tools issue it. This adds a knob to reject kill-servers.
void adb_set_reject_kill_server(bool reject);
#endif

void usb_init();
+18 −2
Original line number Diff line number Diff line
@@ -204,9 +204,25 @@ bool adb_kill_server() {
        return false;
    }

    // The server might send OKAY, so consume that.
    char buf[4];
    ReadFdExactly(fd.get(), buf, 4);
    if (!ReadFdExactly(fd.get(), buf, 4)) {
        fprintf(stderr, "error: failed to read response from server\n");
        return false;
    }

    if (memcmp(buf, "OKAY", 4) == 0) {
        // Nothing to do.
    } else if (memcmp(buf, "FAIL", 4) == 0) {
        std::string output, error;
        if (!ReadProtocolString(fd.get(), &output, &error)) {
            fprintf(stderr, "error: %s\n", error.c_str());
            return false;
        }

        fprintf(stderr, "error: %s\n", output.c_str());
        return false;
    }

    // Now that no more data is expected, wait for socket orderly shutdown or error, indicating
    // server death.
    ReadOrderlyShutdown(fd.get());
+6 −1
Original line number Diff line number Diff line
@@ -105,7 +105,12 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply
        fdevent_run_on_main_thread([]() { exit(0); });
    });

    char* leak = getenv("ADB_LEAK");
    const char* reject_kill_server = getenv("ADB_REJECT_KILL_SERVER");
    if (reject_kill_server && strcmp(reject_kill_server, "1") == 0) {
        adb_set_reject_kill_server(true);
    }

    const char* leak = getenv("ADB_LEAK");
    if (leak && strcmp(leak, "1") == 0) {
        intentionally_leak();
    }