1/*
2 * Copyright (C) 2015 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#if !ADB_HOST
18
19#define TRACE_TAG JDWP
20
21#include "sysdeps.h"
22
23#include <errno.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <sys/socket.h>
28#include <sys/un.h>
29#include <unistd.h>
30
31#include <list>
32#include <memory>
33#include <vector>
34
35#include "adb.h"
36#include "adb_io.h"
37#include "adb_unique_fd.h"
38#include "adb_utils.h"
39
40/* here's how these things work.
41
42   when adbd starts, it creates a unix server socket
43   named @jdwp-control (@ is a shortcut for "first byte is zero"
44   to use the private namespace instead of the file system)
45
46   when a new JDWP daemon thread starts in a new VM process, it creates
47   a connection to @jdwp-control to announce its availability.
48
49
50     JDWP thread                             @jdwp-control
51         |                                         |
52         |------------------------------->         |
53         | hello I'm in process <pid>              |
54         |                                         |
55         |                                         |
56
57    the connection is kept alive. it will be closed automatically if
58    the JDWP process terminates (this allows adbd to detect dead
59    processes).
60
61    adbd thus maintains a list of "active" JDWP processes. it can send
62    its content to clients through the "device:debug-ports" service,
63    or even updates through the "device:track-debug-ports" service.
64
65    when a debugger wants to connect, it simply runs the command
66    equivalent to  "adb forward tcp:<hostport> jdwp:<pid>"
67
68    "jdwp:<pid>" is a new forward destination format used to target
69    a given JDWP process on the device. when sutch a request arrives,
70    adbd does the following:
71
72      - first, it calls socketpair() to create a pair of equivalent
73        sockets.
74
75      - it attaches the first socket in the pair to a local socket
76        which is itself attached to the transport's remote socket:
77
78
79      - it sends the file descriptor of the second socket directly
80        to the JDWP process with the help of sendmsg()
81
82
83     JDWP thread                             @jdwp-control
84         |                                         |
85         |                  <----------------------|
86         |           OK, try this file descriptor  |
87         |                                         |
88         |                                         |
89
90   then, the JDWP thread uses this new socket descriptor as its
91   pass-through connection to the debugger (and receives the
92   JDWP-Handshake message, answers to it, etc...)
93
94   this gives the following graphics:
95                    ____________________________________
96                   |                                    |
97                   |          ADB Server (host)         |
98                   |                                    |
99        Debugger <---> LocalSocket <----> RemoteSocket  |
100                   |                           ^^       |
101                   |___________________________||_______|
102                                               ||
103                                     Transport ||
104           (TCP for emulator - USB for device) ||
105                                               ||
106                    ___________________________||_______
107                   |                           ||       |
108                   |          ADBD  (device)   ||       |
109                   |                           VV       |
110         JDWP <======> LocalSocket <----> RemoteSocket  |
111                   |                                    |
112                   |____________________________________|
113
114    due to the way adb works, this doesn't need a special socket
115    type or fancy handling of socket termination if either the debugger
116    or the JDWP process closes the connection.
117
118    THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN
119    TO HAVE A BETTER IDEA, LET ME KNOW - Digit
120
121**********************************************************************/
122
123/** JDWP PID List Support Code
124 ** for each JDWP process, we record its pid and its connected socket
125 **/
126
127// PIDs are transmitted as 4 hex digits in ascii.
128static constexpr size_t PID_LEN = 4;
129
130static void jdwp_process_event(int socket, unsigned events, void* _proc);
131static void jdwp_process_list_updated(void);
132
133struct JdwpProcess;
134static std::list<std::unique_ptr<JdwpProcess>> _jdwp_list;
135
136struct JdwpProcess {
137    explicit JdwpProcess(int socket) {
138        this->socket = socket;
139        this->fde = fdevent_create(socket, jdwp_process_event, this);
140
141        if (!this->fde) {
142            fatal("could not create fdevent for new JDWP process");
143        }
144
145        this->fde->state |= FDE_DONT_CLOSE;
146
147        /* start by waiting for the PID */
148        fdevent_add(this->fde, FDE_READ);
149    }
150
151    ~JdwpProcess() {
152        if (this->socket >= 0) {
153            adb_shutdown(this->socket);
154            adb_close(this->socket);
155            this->socket = -1;
156        }
157
158        if (this->fde) {
159            fdevent_destroy(this->fde);
160            this->fde = nullptr;
161        }
162
163        out_fds.clear();
164    }
165
166    void RemoveFromList() {
167        if (this->pid >= 0) {
168            D("removing pid %d from jdwp process list", this->pid);
169        } else {
170            D("removing transient JdwpProcess from list");
171        }
172
173        auto pred = [this](const auto& proc) { return proc.get() == this; };
174        _jdwp_list.remove_if(pred);
175    }
176
177    int pid = -1;
178    int socket = -1;
179    fdevent* fde = nullptr;
180
181    std::vector<unique_fd> out_fds;
182};
183
184static size_t jdwp_process_list(char* buffer, size_t bufferlen) {
185    std::string temp;
186
187    for (auto& proc : _jdwp_list) {
188        /* skip transient connections */
189        if (proc->pid < 0) {
190            continue;
191        }
192
193        std::string next = std::to_string(proc->pid) + "\n";
194        if (temp.length() + next.length() > bufferlen) {
195            D("truncating JDWP process list (max len = %zu)", bufferlen);
196            break;
197        }
198        temp.append(next);
199    }
200
201    memcpy(buffer, temp.data(), temp.length());
202    return temp.length();
203}
204
205static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) {
206    // Message is length-prefixed with 4 hex digits in ASCII.
207    static constexpr size_t header_len = 4;
208    if (bufferlen < header_len) {
209        fatal("invalid JDWP process list buffer size: %zu", bufferlen);
210    }
211
212    char head[header_len + 1];
213    size_t len = jdwp_process_list(buffer + header_len, bufferlen - header_len);
214    snprintf(head, sizeof head, "%04zx", len);
215    memcpy(buffer, head, header_len);
216    return len + header_len;
217}
218
219static void jdwp_process_event(int socket, unsigned events, void* _proc) {
220    JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc);
221
222    if (events & FDE_READ) {
223        if (proc->pid < 0) {
224            /* read the PID as a 4-hexchar string */
225            char buf[PID_LEN + 1];
226            ssize_t rc = TEMP_FAILURE_RETRY(recv(socket, buf, PID_LEN, 0));
227            if (rc != PID_LEN) {
228                D("failed to read jdwp pid: %s", strerror(errno));
229                goto CloseProcess;
230            }
231            buf[PID_LEN] = '\0';
232
233            if (sscanf(buf, "%04x", &proc->pid) != 1) {
234                D("could not decode JDWP %p PID number: '%s'", proc, buf);
235                goto CloseProcess;
236            }
237
238            /* all is well, keep reading to detect connection closure */
239            D("Adding pid %d to jdwp process list", proc->pid);
240            jdwp_process_list_updated();
241        } else {
242            /* the pid was read, if we get there it's probably because the connection
243             * was closed (e.g. the JDWP process exited or crashed) */
244            char buf[32];
245
246            while (true) {
247                int len = TEMP_FAILURE_RETRY(recv(socket, buf, sizeof(buf), 0));
248
249                if (len == 0) {
250                    D("terminating JDWP %d connection: EOF", proc->pid);
251                    break;
252                } else if (len < 0) {
253                    if (len < 0 && errno == EAGAIN) {
254                        return;
255                    }
256
257                    D("terminating JDWP %d connection: EOF", proc->pid);
258                    break;
259                } else {
260                    D("ignoring unexpected JDWP %d control socket activity (%d bytes)", proc->pid,
261                      len);
262                }
263            }
264
265            goto CloseProcess;
266        }
267    }
268
269    if (events & FDE_WRITE) {
270        D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size());
271        if (!proc->out_fds.empty()) {
272            int fd = proc->out_fds.back().get();
273            struct cmsghdr* cmsg;
274            struct msghdr msg;
275            struct iovec iov;
276            char dummy = '!';
277            char buffer[sizeof(struct cmsghdr) + sizeof(int)];
278
279            iov.iov_base = &dummy;
280            iov.iov_len = 1;
281            msg.msg_name = NULL;
282            msg.msg_namelen = 0;
283            msg.msg_iov = &iov;
284            msg.msg_iovlen = 1;
285            msg.msg_flags = 0;
286            msg.msg_control = buffer;
287            msg.msg_controllen = sizeof(buffer);
288
289            cmsg = CMSG_FIRSTHDR(&msg);
290            cmsg->cmsg_len = msg.msg_controllen;
291            cmsg->cmsg_level = SOL_SOCKET;
292            cmsg->cmsg_type = SCM_RIGHTS;
293            ((int*)CMSG_DATA(cmsg))[0] = fd;
294
295            if (!set_file_block_mode(proc->socket, true)) {
296                VLOG(JDWP) << "failed to set blocking mode for fd " << proc->socket;
297                goto CloseProcess;
298            }
299
300            int ret = TEMP_FAILURE_RETRY(sendmsg(proc->socket, &msg, 0));
301            if (ret < 0) {
302                D("sending new file descriptor to JDWP %d failed: %s", proc->pid, strerror(errno));
303                goto CloseProcess;
304            }
305
306            adb_close(fd);
307
308            D("sent file descriptor %d to JDWP process %d", fd, proc->pid);
309
310            proc->out_fds.pop_back();
311
312            if (!set_file_block_mode(proc->socket, false)) {
313                VLOG(JDWP) << "failed to set non-blocking mode for fd " << proc->socket;
314                goto CloseProcess;
315            }
316
317            if (proc->out_fds.empty()) {
318                fdevent_del(proc->fde, FDE_WRITE);
319            }
320        }
321    }
322
323    return;
324
325CloseProcess:
326    proc->RemoveFromList();
327    jdwp_process_list_updated();
328}
329
330int create_jdwp_connection_fd(int pid) {
331    D("looking for pid %d in JDWP process list", pid);
332
333    for (auto& proc : _jdwp_list) {
334        if (proc->pid == pid) {
335            int fds[2];
336
337            if (adb_socketpair(fds) < 0) {
338                D("%s: socket pair creation failed: %s", __FUNCTION__, strerror(errno));
339                return -1;
340            }
341            D("socketpair: (%d,%d)", fds[0], fds[1]);
342
343            proc->out_fds.emplace_back(fds[1]);
344            if (proc->out_fds.size() == 1) {
345                fdevent_add(proc->fde, FDE_WRITE);
346            }
347
348            return fds[0];
349        }
350    }
351    D("search failed !!");
352    return -1;
353}
354
355/**  VM DEBUG CONTROL SOCKET
356 **
357 **  we do implement a custom asocket to receive the data
358 **/
359
360/* name of the debug control Unix socket */
361#define JDWP_CONTROL_NAME "\0jdwp-control"
362#define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1)
363
364struct JdwpControl {
365    int listen_socket;
366    fdevent* fde;
367};
368
369static JdwpControl _jdwp_control;
370
371static void jdwp_control_event(int s, unsigned events, void* user);
372
373static int jdwp_control_init(JdwpControl* control, const char* sockname, int socknamelen) {
374    sockaddr_un addr;
375    socklen_t addrlen;
376    int s;
377    int maxpath = sizeof(addr.sun_path);
378    int pathlen = socknamelen;
379
380    if (pathlen >= maxpath) {
381        D("vm debug control socket name too long (%d extra chars)", pathlen + 1 - maxpath);
382        return -1;
383    }
384
385    memset(&addr, 0, sizeof(addr));
386    addr.sun_family = AF_UNIX;
387    memcpy(addr.sun_path, sockname, socknamelen);
388
389    s = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
390    if (s < 0) {
391        D("could not create vm debug control socket. %d: %s", errno, strerror(errno));
392        return -1;
393    }
394
395    addrlen = pathlen + sizeof(addr.sun_family);
396
397    if (bind(s, reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
398        D("could not bind vm debug control socket: %d: %s", errno, strerror(errno));
399        adb_close(s);
400        return -1;
401    }
402
403    if (listen(s, 4) < 0) {
404        D("listen failed in jdwp control socket: %d: %s", errno, strerror(errno));
405        adb_close(s);
406        return -1;
407    }
408
409    control->listen_socket = s;
410
411    control->fde = fdevent_create(s, jdwp_control_event, control);
412    if (control->fde == NULL) {
413        D("could not create fdevent for jdwp control socket");
414        adb_close(s);
415        return -1;
416    }
417
418    /* only wait for incoming connections */
419    fdevent_add(control->fde, FDE_READ);
420
421    D("jdwp control socket started (%d)", control->listen_socket);
422    return 0;
423}
424
425static void jdwp_control_event(int s, unsigned events, void* _control) {
426    JdwpControl* control = (JdwpControl*)_control;
427
428    if (events & FDE_READ) {
429        int s = adb_socket_accept(control->listen_socket, nullptr, nullptr);
430        if (s < 0) {
431            if (errno == ECONNABORTED) {
432                /* oops, the JDWP process died really quick */
433                D("oops, the JDWP process died really quick");
434                return;
435            } else {
436                /* the socket is probably closed ? */
437                D("weird accept() failed on jdwp control socket: %s", strerror(errno));
438                return;
439            }
440        }
441
442        auto proc = std::make_unique<JdwpProcess>(s);
443        if (!proc) {
444            fatal("failed to allocate JdwpProcess");
445        }
446
447        _jdwp_list.emplace_back(std::move(proc));
448    }
449}
450
451/** "jdwp" local service implementation
452 ** this simply returns the list of known JDWP process pids
453 **/
454
455struct JdwpSocket : public asocket {
456    bool pass;
457};
458
459static void jdwp_socket_close(asocket* s) {
460    D("LS(%d): closing jdwp socket", s->id);
461
462    if (s->peer) {
463        D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
464        s->peer->peer = nullptr;
465        s->peer->close(s->peer);
466        s->peer = nullptr;
467    }
468
469    remove_socket(s);
470    free(s);
471}
472
473static int jdwp_socket_enqueue(asocket* s, apacket* p) {
474    /* you can't write to this asocket */
475    D("LS(%d): JDWP socket received data?", s->id);
476    put_apacket(p);
477    s->peer->close(s->peer);
478    return -1;
479}
480
481static void jdwp_socket_ready(asocket* s) {
482    JdwpSocket* jdwp = (JdwpSocket*)s;
483    asocket* peer = jdwp->peer;
484
485    /* on the first call, send the list of pids,
486     * on the second one, close the connection
487     */
488    if (!jdwp->pass) {
489        apacket* p = get_apacket();
490        p->len = jdwp_process_list((char*)p->data, s->get_max_payload());
491        peer->enqueue(peer, p);
492        jdwp->pass = true;
493    } else {
494        peer->close(peer);
495    }
496}
497
498asocket* create_jdwp_service_socket(void) {
499    JdwpSocket* s = reinterpret_cast<JdwpSocket*>(calloc(sizeof(*s), 1));
500
501    if (!s) {
502        fatal("failed to allocate JdwpSocket");
503    }
504
505    install_local_socket(s);
506
507    s->ready = jdwp_socket_ready;
508    s->enqueue = jdwp_socket_enqueue;
509    s->close = jdwp_socket_close;
510    s->pass = false;
511
512    return s;
513}
514
515/** "track-jdwp" local service implementation
516 ** this periodically sends the list of known JDWP process pids
517 ** to the client...
518 **/
519
520struct JdwpTracker : public asocket {
521    bool need_initial;
522};
523
524static std::vector<std::unique_ptr<JdwpTracker>> _jdwp_trackers;
525
526static void jdwp_process_list_updated(void) {
527    char buffer[1024];
528    int len = jdwp_process_list_msg(buffer, sizeof(buffer));
529
530    for (auto& t : _jdwp_trackers) {
531        apacket* p = get_apacket();
532        memcpy(p->data, buffer, len);
533        p->len = len;
534
535        if (t->peer) {
536            // The tracker might not have been connected yet.
537            t->peer->enqueue(t->peer, p);
538        }
539    }
540}
541
542static void jdwp_tracker_close(asocket* s) {
543    D("LS(%d): destroying jdwp tracker service", s->id);
544
545    if (s->peer) {
546        D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
547        s->peer->peer = nullptr;
548        s->peer->close(s->peer);
549        s->peer = nullptr;
550    }
551
552    remove_socket(s);
553
554    auto pred = [s](const auto& tracker) { return tracker.get() == s; };
555    _jdwp_trackers.erase(std::remove_if(_jdwp_trackers.begin(), _jdwp_trackers.end(), pred),
556                         _jdwp_trackers.end());
557}
558
559static void jdwp_tracker_ready(asocket* s) {
560    JdwpTracker* t = (JdwpTracker*)s;
561
562    if (t->need_initial) {
563        apacket* p = get_apacket();
564        t->need_initial = false;
565        p->len = jdwp_process_list_msg((char*)p->data, s->get_max_payload());
566        s->peer->enqueue(s->peer, p);
567    }
568}
569
570static int jdwp_tracker_enqueue(asocket* s, apacket* p) {
571    /* you can't write to this socket */
572    D("LS(%d): JDWP tracker received data?", s->id);
573    put_apacket(p);
574    s->peer->close(s->peer);
575    return -1;
576}
577
578asocket* create_jdwp_tracker_service_socket(void) {
579    auto t = std::make_unique<JdwpTracker>();
580    if (!t) {
581        fatal("failed to allocate JdwpTracker");
582    }
583
584    memset(t.get(), 0, sizeof(asocket));
585
586    install_local_socket(t.get());
587    D("LS(%d): created new jdwp tracker service", t->id);
588
589    t->ready = jdwp_tracker_ready;
590    t->enqueue = jdwp_tracker_enqueue;
591    t->close = jdwp_tracker_close;
592    t->need_initial = true;
593
594    asocket* result = t.get();
595
596    _jdwp_trackers.emplace_back(std::move(t));
597
598    return result;
599}
600
601int init_jdwp(void) {
602    return jdwp_control_init(&_jdwp_control, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN);
603}
604
605#endif /* !ADB_HOST */
606