services.cpp revision 6ac5d7dc56a016718d2a26803435505e983e5d80
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define TRACE_TAG TRACE_SERVICES
18
19#include "sysdeps.h"
20
21#include <errno.h>
22#include <stddef.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#if !ADB_HOST
28#include <pty.h>
29#include <termios.h>
30#endif
31
32#ifndef _WIN32
33#include <netdb.h>
34#include <netinet/in.h>
35#include <sys/ioctl.h>
36#include <unistd.h>
37#endif
38
39#include <base/file.h>
40#include <base/stringprintf.h>
41#include <base/strings.h>
42
43#if !ADB_HOST
44#include "cutils/android_reboot.h"
45#include "cutils/properties.h"
46#endif
47
48#include "adb.h"
49#include "adb_io.h"
50#include "file_sync_service.h"
51#include "remount_service.h"
52#include "transport.h"
53
54struct stinfo {
55    void (*func)(int fd, void *cookie);
56    int fd;
57    void *cookie;
58};
59
60
61void *service_bootstrap_func(void *x)
62{
63    stinfo* sti = reinterpret_cast<stinfo*>(x);
64    sti->func(sti->fd, sti->cookie);
65    free(sti);
66    return 0;
67}
68
69#if !ADB_HOST
70
71void restart_root_service(int fd, void *cookie) {
72    if (getuid() == 0) {
73        WriteFdExactly(fd, "adbd is already running as root\n");
74        adb_close(fd);
75    } else {
76        char value[PROPERTY_VALUE_MAX];
77        property_get("ro.debuggable", value, "");
78        if (strcmp(value, "1") != 0) {
79            WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
80            adb_close(fd);
81            return;
82        }
83
84        property_set("service.adb.root", "1");
85        WriteFdExactly(fd, "restarting adbd as root\n");
86        adb_close(fd);
87    }
88}
89
90void restart_unroot_service(int fd, void *cookie) {
91    if (getuid() != 0) {
92        WriteFdExactly(fd, "adbd not running as root\n");
93        adb_close(fd);
94    } else {
95        property_set("service.adb.root", "0");
96        WriteFdExactly(fd, "restarting adbd as non root\n");
97        adb_close(fd);
98    }
99}
100
101void restart_tcp_service(int fd, void *cookie) {
102    int port = (int) (uintptr_t) cookie;
103    if (port <= 0) {
104        WriteFdFmt(fd, "invalid port %d\n", port);
105        adb_close(fd);
106        return;
107    }
108
109    char value[PROPERTY_VALUE_MAX];
110    snprintf(value, sizeof(value), "%d", port);
111    property_set("service.adb.tcp.port", value);
112    WriteFdFmt(fd, "restarting in TCP mode port: %d\n", port);
113    adb_close(fd);
114}
115
116void restart_usb_service(int fd, void *cookie) {
117    property_set("service.adb.tcp.port", "0");
118    WriteFdExactly(fd, "restarting in USB mode\n");
119    adb_close(fd);
120}
121
122static bool reboot_service_impl(int fd, const char* arg) {
123    const char* reboot_arg = arg;
124    bool auto_reboot = false;
125
126    if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) {
127        auto_reboot = true;
128        reboot_arg = "sideload";
129    }
130
131    // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot"
132    // in the command file.
133    if (strcmp(reboot_arg, "sideload") == 0) {
134        if (getuid() != 0) {
135            WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n");
136            return false;
137        }
138
139        const char* const recovery_dir = "/cache/recovery";
140        const char* const command_file = "/cache/recovery/command";
141        // Ensure /cache/recovery exists.
142        if (adb_mkdir(recovery_dir, 0770) == -1 && errno != EEXIST) {
143            D("Failed to create directory '%s': %s\n", recovery_dir, strerror(errno));
144            return false;
145        }
146
147        bool write_status = android::base::WriteStringToFile(
148                auto_reboot ? "--sideload_auto_reboot" : "--sideload", command_file);
149        if (!write_status) {
150            return false;
151        }
152
153        reboot_arg = "recovery";
154    }
155
156    sync();
157
158    char property_val[PROPERTY_VALUE_MAX];
159    int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg);
160    if (ret >= static_cast<int>(sizeof(property_val))) {
161        WriteFdFmt(fd, "reboot string too long: %d\n", ret);
162        return false;
163    }
164
165    ret = property_set(ANDROID_RB_PROPERTY, property_val);
166    if (ret < 0) {
167        WriteFdFmt(fd, "reboot failed: %d\n", ret);
168        return false;
169    }
170
171    return true;
172}
173
174void reboot_service(int fd, void* arg)
175{
176    if (reboot_service_impl(fd, static_cast<const char*>(arg))) {
177        // Don't return early. Give the reboot command time to take effect
178        // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
179        while (true) {
180            pause();
181        }
182    }
183
184    free(arg);
185    adb_close(fd);
186}
187
188void reverse_service(int fd, void* arg)
189{
190    const char* command = reinterpret_cast<const char*>(arg);
191
192    if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
193        SendFail(fd, "not a reverse forwarding command");
194    }
195    free(arg);
196    adb_close(fd);
197}
198
199#endif
200
201static int create_service_thread(void (*func)(int, void *), void *cookie)
202{
203    int s[2];
204    if (adb_socketpair(s)) {
205        printf("cannot create service socket pair\n");
206        return -1;
207    }
208    D("socketpair: (%d,%d)", s[0], s[1]);
209
210    stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
211    if (sti == nullptr) {
212        fatal("cannot allocate stinfo");
213    }
214    sti->func = func;
215    sti->cookie = cookie;
216    sti->fd = s[1];
217
218    if (!adb_thread_create(service_bootstrap_func, sti)) {
219        free(sti);
220        adb_close(s[0]);
221        adb_close(s[1]);
222        printf("cannot create service thread\n");
223        return -1;
224    }
225
226    D("service thread started, %d:%d\n",s[0], s[1]);
227    return s[0];
228}
229
230#if !ADB_HOST
231
232static void init_subproc_child()
233{
234    setsid();
235
236    // Set OOM score adjustment to prevent killing
237    int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
238    if (fd >= 0) {
239        adb_write(fd, "0", 1);
240        adb_close(fd);
241    } else {
242       D("adb: unable to update oom_score_adj\n");
243    }
244}
245
246#if !ADB_HOST
247static int create_subproc_pty(const char* cmd, const char* arg0,
248                              const char* arg1, pid_t* pid) {
249    D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
250    char pts_name[PATH_MAX];
251    int ptm;
252    *pid = forkpty(&ptm, pts_name, nullptr, nullptr);
253    if (*pid == -1) {
254        printf("- fork failed: %s -\n", strerror(errno));
255        unix_close(ptm);
256        return -1;
257    }
258
259    if (*pid == 0) {
260        init_subproc_child();
261
262        int pts = unix_open(pts_name, O_RDWR | O_CLOEXEC);
263        if (pts == -1) {
264            fprintf(stderr, "child failed to open pseudo-term slave %s: %s\n",
265                    pts_name, strerror(errno));
266            unix_close(ptm);
267            exit(-1);
268        }
269
270        // arg0 is "-c" in batch mode and "-" in interactive mode.
271        if (strcmp(arg0, "-c") == 0) {
272            termios tattr;
273            if (tcgetattr(pts, &tattr) == -1) {
274                fprintf(stderr, "tcgetattr failed: %s\n", strerror(errno));
275                unix_close(pts);
276                unix_close(ptm);
277                exit(-1);
278            }
279
280            cfmakeraw(&tattr);
281            if (tcsetattr(pts, TCSADRAIN, &tattr) == -1) {
282                fprintf(stderr, "tcsetattr failed: %s\n", strerror(errno));
283                unix_close(pts);
284                unix_close(ptm);
285                exit(-1);
286            }
287        }
288
289        dup2(pts, STDIN_FILENO);
290        dup2(pts, STDOUT_FILENO);
291        dup2(pts, STDERR_FILENO);
292
293        unix_close(pts);
294        unix_close(ptm);
295
296        execl(cmd, cmd, arg0, arg1, nullptr);
297        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
298                cmd, strerror(errno), errno);
299        exit(-1);
300    } else {
301        return ptm;
302    }
303}
304#endif // !ADB_HOST
305
306static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
307{
308    D("create_subproc_raw(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
309#if defined(_WIN32)
310    fprintf(stderr, "error: create_subproc_raw not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
311    return -1;
312#else
313
314    // 0 is parent socket, 1 is child socket
315    int sv[2];
316    if (adb_socketpair(sv) < 0) {
317        printf("[ cannot create socket pair - %s ]\n", strerror(errno));
318        return -1;
319    }
320    D("socketpair: (%d,%d)", sv[0], sv[1]);
321
322    *pid = fork();
323    if (*pid < 0) {
324        printf("- fork failed: %s -\n", strerror(errno));
325        adb_close(sv[0]);
326        adb_close(sv[1]);
327        return -1;
328    }
329
330    if (*pid == 0) {
331        adb_close(sv[0]);
332        init_subproc_child();
333
334        dup2(sv[1], STDIN_FILENO);
335        dup2(sv[1], STDOUT_FILENO);
336        dup2(sv[1], STDERR_FILENO);
337
338        adb_close(sv[1]);
339
340        execl(cmd, cmd, arg0, arg1, NULL);
341        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
342                cmd, strerror(errno), errno);
343        exit(-1);
344    } else {
345        adb_close(sv[1]);
346        return sv[0];
347    }
348#endif /* !defined(_WIN32) */
349}
350#endif  /* !ABD_HOST */
351
352#if ADB_HOST
353#define SHELL_COMMAND "/bin/sh"
354#else
355#define SHELL_COMMAND "/system/bin/sh"
356#endif
357
358#if !ADB_HOST
359static void subproc_waiter_service(int fd, void *cookie)
360{
361    pid_t pid = (pid_t) (uintptr_t) cookie;
362
363    D("entered. fd=%d of pid=%d\n", fd, pid);
364    while (true) {
365        int status;
366        pid_t p = waitpid(pid, &status, 0);
367        if (p == pid) {
368            D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status);
369            if (WIFSIGNALED(status)) {
370                D("*** Killed by signal %d\n", WTERMSIG(status));
371                break;
372            } else if (!WIFEXITED(status)) {
373                D("*** Didn't exit!!. status %d\n", status);
374                break;
375            } else if (WEXITSTATUS(status) >= 0) {
376                D("*** Exit code %d\n", WEXITSTATUS(status));
377                break;
378            }
379         }
380    }
381    D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno);
382    if (SHELL_EXIT_NOTIFY_FD >=0) {
383      int res;
384      res = WriteFdExactly(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)) ? 0 : -1;
385      D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n",
386        SHELL_EXIT_NOTIFY_FD, pid, res, errno);
387    }
388}
389
390static int create_subproc_thread(const char *name, bool pty = false) {
391    const char *arg0, *arg1;
392    if (name == 0 || *name == 0) {
393        arg0 = "-"; arg1 = 0;
394    } else {
395        arg0 = "-c"; arg1 = name;
396    }
397
398    pid_t pid = -1;
399    int ret_fd;
400    if (pty) {
401        ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid);
402    } else {
403        ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid);
404    }
405    D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid);
406
407    stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
408    if(sti == 0) fatal("cannot allocate stinfo");
409    sti->func = subproc_waiter_service;
410    sti->cookie = (void*) (uintptr_t) pid;
411    sti->fd = ret_fd;
412
413    if (!adb_thread_create(service_bootstrap_func, sti)) {
414        free(sti);
415        adb_close(ret_fd);
416        fprintf(stderr, "cannot create service thread\n");
417        return -1;
418    }
419
420    D("service thread started, fd=%d pid=%d\n", ret_fd, pid);
421    return ret_fd;
422}
423#endif
424
425int service_to_fd(const char *name)
426{
427    int ret = -1;
428
429    if(!strncmp(name, "tcp:", 4)) {
430        int port = atoi(name + 4);
431        name = strchr(name + 4, ':');
432        if(name == 0) {
433            ret = socket_loopback_client(port, SOCK_STREAM);
434            if (ret >= 0)
435                disable_tcp_nagle(ret);
436        } else {
437#if ADB_HOST
438            ret = socket_network_client(name + 1, port, SOCK_STREAM);
439#else
440            return -1;
441#endif
442        }
443#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
444    } else if(!strncmp(name, "local:", 6)) {
445        ret = socket_local_client(name + 6,
446                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
447    } else if(!strncmp(name, "localreserved:", 14)) {
448        ret = socket_local_client(name + 14,
449                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
450    } else if(!strncmp(name, "localabstract:", 14)) {
451        ret = socket_local_client(name + 14,
452                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
453    } else if(!strncmp(name, "localfilesystem:", 16)) {
454        ret = socket_local_client(name + 16,
455                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
456#endif
457#if !ADB_HOST
458    } else if(!strncmp("dev:", name, 4)) {
459        ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
460    } else if(!strncmp(name, "framebuffer:", 12)) {
461        ret = create_service_thread(framebuffer_service, 0);
462    } else if (!strncmp(name, "jdwp:", 5)) {
463        ret = create_jdwp_connection_fd(atoi(name+5));
464    } else if(!HOST && !strncmp(name, "shell:", 6)) {
465        ret = create_subproc_thread(name + 6, true);
466    } else if(!HOST && !strncmp(name, "exec:", 5)) {
467        ret = create_subproc_thread(name + 5);
468    } else if(!strncmp(name, "sync:", 5)) {
469        ret = create_service_thread(file_sync_service, NULL);
470    } else if(!strncmp(name, "remount:", 8)) {
471        ret = create_service_thread(remount_service, NULL);
472    } else if(!strncmp(name, "reboot:", 7)) {
473        void* arg = strdup(name + 7);
474        if (arg == NULL) return -1;
475        ret = create_service_thread(reboot_service, arg);
476    } else if(!strncmp(name, "root:", 5)) {
477        ret = create_service_thread(restart_root_service, NULL);
478    } else if(!strncmp(name, "unroot:", 7)) {
479        ret = create_service_thread(restart_unroot_service, NULL);
480    } else if(!strncmp(name, "backup:", 7)) {
481        ret = create_subproc_thread(android::base::StringPrintf("/system/bin/bu backup %s",
482                                                                (name + 7)).c_str());
483    } else if(!strncmp(name, "restore:", 8)) {
484        ret = create_subproc_thread("/system/bin/bu restore");
485    } else if(!strncmp(name, "tcpip:", 6)) {
486        int port;
487        if (sscanf(name + 6, "%d", &port) != 1) {
488            port = 0;
489        }
490        ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port);
491    } else if(!strncmp(name, "usb:", 4)) {
492        ret = create_service_thread(restart_usb_service, NULL);
493    } else if (!strncmp(name, "reverse:", 8)) {
494        char* cookie = strdup(name + 8);
495        if (cookie == NULL) {
496            ret = -1;
497        } else {
498            ret = create_service_thread(reverse_service, cookie);
499            if (ret < 0) {
500                free(cookie);
501            }
502        }
503    } else if(!strncmp(name, "disable-verity:", 15)) {
504        ret = create_service_thread(set_verity_enabled_state_service, (void*)0);
505    } else if(!strncmp(name, "enable-verity:", 15)) {
506        ret = create_service_thread(set_verity_enabled_state_service, (void*)1);
507#endif
508    }
509    if (ret >= 0) {
510        close_on_exec(ret);
511    }
512    return ret;
513}
514
515#if ADB_HOST
516struct state_info {
517    TransportType transport_type;
518    char* serial;
519    ConnectionState state;
520};
521
522static void wait_for_state(int fd, void* cookie)
523{
524    state_info* sinfo = reinterpret_cast<state_info*>(cookie);
525
526    D("wait_for_state %d\n", sinfo->state);
527
528    std::string error_msg = "unknown error";
529    atransport* t = acquire_one_transport(sinfo->state, sinfo->transport_type, sinfo->serial,
530                                          &error_msg);
531    if (t != 0) {
532        SendOkay(fd);
533    } else {
534        SendFail(fd, error_msg);
535    }
536
537    if (sinfo->serial)
538        free(sinfo->serial);
539    free(sinfo);
540    adb_close(fd);
541    D("wait_for_state is done\n");
542}
543
544static void connect_device(const std::string& host, std::string* response) {
545    if (host.empty()) {
546        *response = "empty host name";
547        return;
548    }
549
550    std::vector<std::string> pieces = android::base::Split(host, ":");
551    const std::string& hostname = pieces[0];
552
553    int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
554    if (pieces.size() > 1) {
555        if (sscanf(pieces[1].c_str(), "%d", &port) != 1) {
556            *response = android::base::StringPrintf("bad port number %s", pieces[1].c_str());
557            return;
558        }
559    }
560
561    // This may look like we're putting 'host' back together,
562    // but we're actually inserting the default port if necessary.
563    std::string serial = android::base::StringPrintf("%s:%d", hostname.c_str(), port);
564
565    int fd = socket_network_client_timeout(hostname.c_str(), port, SOCK_STREAM, 10);
566    if (fd < 0) {
567        *response = android::base::StringPrintf("unable to connect to %s:%d",
568                                                hostname.c_str(), port);
569        return;
570    }
571
572    D("client: connected on remote on fd %d\n", fd);
573    close_on_exec(fd);
574    disable_tcp_nagle(fd);
575
576    int ret = register_socket_transport(fd, serial.c_str(), port, 0);
577    if (ret < 0) {
578        adb_close(fd);
579        *response = android::base::StringPrintf("already connected to %s", serial.c_str());
580    } else {
581        *response = android::base::StringPrintf("connected to %s", serial.c_str());
582    }
583}
584
585void connect_emulator(const std::string& port_spec, std::string* response) {
586    std::vector<std::string> pieces = android::base::Split(port_spec, ",");
587    if (pieces.size() != 2) {
588        *response = android::base::StringPrintf("unable to parse '%s' as <console port>,<adb port>",
589                                                port_spec.c_str());
590        return;
591    }
592
593    int console_port = strtol(pieces[0].c_str(), NULL, 0);
594    int adb_port = strtol(pieces[1].c_str(), NULL, 0);
595    if (console_port <= 0 || adb_port <= 0) {
596        *response = android::base::StringPrintf("Invalid port numbers: %s", port_spec.c_str());
597        return;
598    }
599
600    // Check if the emulator is already known.
601    // Note: There's a small but harmless race condition here: An emulator not
602    // present just yet could be registered by another invocation right
603    // after doing this check here. However, local_connect protects
604    // against double-registration too. From here, a better error message
605    // can be produced. In the case of the race condition, the very specific
606    // error message won't be shown, but the data doesn't get corrupted.
607    atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);
608    if (known_emulator != nullptr) {
609        *response = android::base::StringPrintf("Emulator already registered on port %d", adb_port);
610        return;
611    }
612
613    // Check if more emulators can be registered. Similar unproblematic
614    // race condition as above.
615    int candidate_slot = get_available_local_transport_index();
616    if (candidate_slot < 0) {
617        *response = "Cannot accept more emulators";
618        return;
619    }
620
621    // Preconditions met, try to connect to the emulator.
622    if (!local_connect_arbitrary_ports(console_port, adb_port)) {
623        *response = android::base::StringPrintf("Connected to emulator on ports %d,%d",
624                                                console_port, adb_port);
625    } else {
626        *response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d",
627                                                console_port, adb_port);
628    }
629}
630
631static void connect_service(int fd, void* data) {
632    char* host = reinterpret_cast<char*>(data);
633    std::string response;
634    if (!strncmp(host, "emu:", 4)) {
635        connect_emulator(host + 4, &response);
636    } else {
637        connect_device(host, &response);
638    }
639    free(host);
640
641    // Send response for emulator and device
642    SendProtocolString(fd, response);
643    adb_close(fd);
644}
645#endif
646
647#if ADB_HOST
648asocket*  host_service_to_socket(const char*  name, const char *serial)
649{
650    if (!strcmp(name,"track-devices")) {
651        return create_device_tracker();
652    } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
653        auto sinfo = reinterpret_cast<state_info*>(malloc(sizeof(state_info)));
654        if (sinfo == nullptr) {
655            fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
656            return NULL;
657        }
658
659        if (serial)
660            sinfo->serial = strdup(serial);
661        else
662            sinfo->serial = NULL;
663
664        name += strlen("wait-for-");
665
666        if (!strncmp(name, "local", strlen("local"))) {
667            sinfo->transport_type = kTransportLocal;
668            sinfo->state = kCsDevice;
669        } else if (!strncmp(name, "usb", strlen("usb"))) {
670            sinfo->transport_type = kTransportUsb;
671            sinfo->state = kCsDevice;
672        } else if (!strncmp(name, "any", strlen("any"))) {
673            sinfo->transport_type = kTransportAny;
674            sinfo->state = kCsDevice;
675        } else {
676            if (sinfo->serial) {
677                free(sinfo->serial);
678            }
679            free(sinfo);
680            return NULL;
681        }
682
683        int fd = create_service_thread(wait_for_state, sinfo);
684        return create_local_socket(fd);
685    } else if (!strncmp(name, "connect:", 8)) {
686        char* host = strdup(name + 8);
687        int fd = create_service_thread(connect_service, host);
688        return create_local_socket(fd);
689    }
690    return NULL;
691}
692#endif /* ADB_HOST */
693