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/* implement the "debug-ports" and "track-debug-ports" device services */
18
19#define TRACE_TAG TRACE_JDWP
20
21#include "sysdeps.h"
22
23#include <errno.h>
24#include <stdio.h>
25#include <string.h>
26#include <unistd.h>
27
28#include "adb.h"
29
30/* here's how these things work.
31
32   when adbd starts, it creates a unix server socket
33   named @vm-debug-control (@ is a shortcut for "first byte is zero"
34   to use the private namespace instead of the file system)
35
36   when a new JDWP daemon thread starts in a new VM process, it creates
37   a connection to @vm-debug-control to announce its availability.
38
39
40     JDWP thread                             @vm-debug-control
41         |                                         |
42         |------------------------------->         |
43         | hello I'm in process <pid>              |
44         |                                         |
45         |                                         |
46
47    the connection is kept alive. it will be closed automatically if
48    the JDWP process terminates (this allows adbd to detect dead
49    processes).
50
51    adbd thus maintains a list of "active" JDWP processes. it can send
52    its content to clients through the "device:debug-ports" service,
53    or even updates through the "device:track-debug-ports" service.
54
55    when a debugger wants to connect, it simply runs the command
56    equivalent to  "adb forward tcp:<hostport> jdwp:<pid>"
57
58    "jdwp:<pid>" is a new forward destination format used to target
59    a given JDWP process on the device. when sutch a request arrives,
60    adbd does the following:
61
62      - first, it calls socketpair() to create a pair of equivalent
63        sockets.
64
65      - it attaches the first socket in the pair to a local socket
66        which is itself attached to the transport's remote socket:
67
68
69      - it sends the file descriptor of the second socket directly
70        to the JDWP process with the help of sendmsg()
71
72
73     JDWP thread                             @vm-debug-control
74         |                                         |
75         |                  <----------------------|
76         |           OK, try this file descriptor  |
77         |                                         |
78         |                                         |
79
80   then, the JDWP thread uses this new socket descriptor as its
81   pass-through connection to the debugger (and receives the
82   JDWP-Handshake message, answers to it, etc...)
83
84   this gives the following graphics:
85                    ____________________________________
86                   |                                    |
87                   |          ADB Server (host)         |
88                   |                                    |
89        Debugger <---> LocalSocket <----> RemoteSocket  |
90                   |                           ^^       |
91                   |___________________________||_______|
92                                               ||
93                                     Transport ||
94           (TCP for emulator - USB for device) ||
95                                               ||
96                    ___________________________||_______
97                   |                           ||       |
98                   |          ADBD  (device)   ||       |
99                   |                           VV       |
100         JDWP <======> LocalSocket <----> RemoteSocket  |
101                   |                                    |
102                   |____________________________________|
103
104    due to the way adb works, this doesn't need a special socket
105    type or fancy handling of socket termination if either the debugger
106    or the JDWP process closes the connection.
107
108    THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN
109    TO HAVE A BETTER IDEA, LET ME KNOW - Digit
110
111**********************************************************************/
112
113/** JDWP PID List Support Code
114 ** for each JDWP process, we record its pid and its connected socket
115 **/
116
117#define  MAX_OUT_FDS   4
118
119#if !ADB_HOST
120
121#include <sys/socket.h>
122#include <sys/un.h>
123
124struct JdwpProcess {
125    JdwpProcess*  next;
126    JdwpProcess*  prev;
127    int           pid;
128    int           socket;
129    fdevent*      fde;
130
131    char          in_buff[4];  /* input character to read PID */
132    int           in_len;      /* number from JDWP process    */
133
134    int           out_fds[MAX_OUT_FDS]; /* output array of file descriptors */
135    int           out_count;            /* to send to the JDWP process      */
136};
137
138static JdwpProcess  _jdwp_list;
139
140static int
141jdwp_process_list( char*  buffer, int  bufferlen )
142{
143    char*         end  = buffer + bufferlen;
144    char*         p    = buffer;
145    JdwpProcess*  proc = _jdwp_list.next;
146
147    for ( ; proc != &_jdwp_list; proc = proc->next ) {
148        int  len;
149
150        /* skip transient connections */
151        if (proc->pid < 0)
152            continue;
153
154        len = snprintf(p, end-p, "%d\n", proc->pid);
155        if (p + len >= end)
156            break;
157        p += len;
158    }
159    p[0] = 0;
160    return (p - buffer);
161}
162
163
164static int
165jdwp_process_list_msg( char*  buffer, int  bufferlen )
166{
167    char  head[5];
168    int   len = jdwp_process_list( buffer+4, bufferlen-4 );
169    snprintf(head, sizeof head, "%04x", len);
170    memcpy(buffer, head, 4);
171    return len + 4;
172}
173
174
175static void  jdwp_process_list_updated(void);
176
177static void
178jdwp_process_free( JdwpProcess*  proc )
179{
180    if (proc) {
181        int  n;
182
183        proc->prev->next = proc->next;
184        proc->next->prev = proc->prev;
185
186        if (proc->socket >= 0) {
187            adb_shutdown(proc->socket);
188            adb_close(proc->socket);
189            proc->socket = -1;
190        }
191
192        if (proc->fde != NULL) {
193            fdevent_destroy(proc->fde);
194            proc->fde = NULL;
195        }
196        proc->pid = -1;
197
198        for (n = 0; n < proc->out_count; n++) {
199            adb_close(proc->out_fds[n]);
200        }
201        proc->out_count = 0;
202
203        free(proc);
204
205        jdwp_process_list_updated();
206    }
207}
208
209
210static void  jdwp_process_event(int, unsigned, void*);  /* forward */
211
212
213static JdwpProcess*
214jdwp_process_alloc( int  socket )
215{
216    JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(
217        calloc(1, sizeof(*proc)));
218
219    if (proc == NULL) {
220        D("not enough memory to create new JDWP process\n");
221        return NULL;
222    }
223
224    proc->socket = socket;
225    proc->pid    = -1;
226    proc->next   = proc;
227    proc->prev   = proc;
228
229    proc->fde = fdevent_create( socket, jdwp_process_event, proc );
230    if (proc->fde == NULL) {
231        D("could not create fdevent for new JDWP process\n" );
232        free(proc);
233        return NULL;
234    }
235
236    proc->fde->state |= FDE_DONT_CLOSE;
237    proc->in_len      = 0;
238    proc->out_count   = 0;
239
240    /* append to list */
241    proc->next = &_jdwp_list;
242    proc->prev = proc->next->prev;
243
244    proc->prev->next = proc;
245    proc->next->prev = proc;
246
247    /* start by waiting for the PID */
248    fdevent_add(proc->fde, FDE_READ);
249
250    return proc;
251}
252
253
254static void
255jdwp_process_event( int  socket, unsigned  events, void*  _proc )
256{
257    JdwpProcess*  proc = reinterpret_cast<JdwpProcess*>(_proc);
258
259    if (events & FDE_READ) {
260        if (proc->pid < 0) {
261            /* read the PID as a 4-hexchar string */
262            char*  p    = proc->in_buff + proc->in_len;
263            int    size = 4 - proc->in_len;
264            char   temp[5];
265            while (size > 0) {
266                int  len = recv( socket, p, size, 0 );
267                if (len < 0) {
268                    if (errno == EINTR)
269                        continue;
270                    if (errno == EAGAIN)
271                        return;
272                    /* this can fail here if the JDWP process crashes very fast */
273                    D("weird unknown JDWP process failure: %s\n",
274                      strerror(errno));
275
276                    goto CloseProcess;
277                }
278                if (len == 0) {  /* end of stream ? */
279                    D("weird end-of-stream from unknown JDWP process\n");
280                    goto CloseProcess;
281                }
282                p            += len;
283                proc->in_len += len;
284                size         -= len;
285            }
286            /* we have read 4 characters, now decode the pid */
287            memcpy(temp, proc->in_buff, 4);
288            temp[4] = 0;
289
290            if (sscanf( temp, "%04x", &proc->pid ) != 1) {
291                D("could not decode JDWP %p PID number: '%s'\n", proc, temp);
292                goto CloseProcess;
293            }
294
295            /* all is well, keep reading to detect connection closure */
296            D("Adding pid %d to jdwp process list\n", proc->pid);
297            jdwp_process_list_updated();
298        }
299        else
300        {
301            /* the pid was read, if we get there it's probably because the connection
302             * was closed (e.g. the JDWP process exited or crashed) */
303            char  buf[32];
304
305            for (;;) {
306                int  len = recv(socket, buf, sizeof(buf), 0);
307
308                if (len <= 0) {
309                    if (len < 0 && errno == EINTR)
310                        continue;
311                    if (len < 0 && errno == EAGAIN)
312                        return;
313                    else {
314                        D("terminating JDWP %d connection: %s\n", proc->pid,
315                          strerror(errno));
316                        break;
317                    }
318                }
319                else {
320                    D( "ignoring unexpected JDWP %d control socket activity (%d bytes)\n",
321                       proc->pid, len );
322                }
323            }
324
325        CloseProcess:
326            if (proc->pid >= 0)
327                D( "remove pid %d to jdwp process list\n", proc->pid );
328            jdwp_process_free(proc);
329            return;
330        }
331    }
332
333    if (events & FDE_WRITE) {
334        D("trying to write to JDWP pid controli (count=%d first=%d) %d\n",
335          proc->pid, proc->out_count, proc->out_fds[0]);
336        if (proc->out_count > 0) {
337            int  fd = proc->out_fds[0];
338            int  n, ret;
339            struct cmsghdr*  cmsg;
340            struct msghdr    msg;
341            struct iovec     iov;
342            char             dummy = '!';
343            char             buffer[sizeof(struct cmsghdr) + sizeof(int)];
344            int flags;
345
346            iov.iov_base       = &dummy;
347            iov.iov_len        = 1;
348            msg.msg_name       = NULL;
349            msg.msg_namelen    = 0;
350            msg.msg_iov        = &iov;
351            msg.msg_iovlen     = 1;
352            msg.msg_flags      = 0;
353            msg.msg_control    = buffer;
354            msg.msg_controllen = sizeof(buffer);
355
356            cmsg = CMSG_FIRSTHDR(&msg);
357            cmsg->cmsg_len   = msg.msg_controllen;
358            cmsg->cmsg_level = SOL_SOCKET;
359            cmsg->cmsg_type  = SCM_RIGHTS;
360            ((int*)CMSG_DATA(cmsg))[0] = fd;
361
362            flags = fcntl(proc->socket,F_GETFL,0);
363
364            if (flags == -1) {
365                D("failed to get cntl flags for socket %d: %s\n",
366                  proc->pid, strerror(errno));
367                goto CloseProcess;
368
369            }
370
371            if (fcntl(proc->socket, F_SETFL, flags & ~O_NONBLOCK) == -1) {
372                D("failed to remove O_NONBLOCK flag for socket %d: %s\n",
373                  proc->pid, strerror(errno));
374                goto CloseProcess;
375            }
376
377            for (;;) {
378                ret = sendmsg(proc->socket, &msg, 0);
379                if (ret >= 0) {
380                    adb_close(fd);
381                    break;
382                }
383                if (errno == EINTR)
384                    continue;
385                D("sending new file descriptor to JDWP %d failed: %s\n",
386                  proc->pid, strerror(errno));
387                goto CloseProcess;
388            }
389
390            D("sent file descriptor %d to JDWP process %d\n",
391              fd, proc->pid);
392
393            for (n = 1; n < proc->out_count; n++)
394                proc->out_fds[n-1] = proc->out_fds[n];
395
396            if (fcntl(proc->socket, F_SETFL, flags) == -1) {
397                D("failed to set O_NONBLOCK flag for socket %d: %s\n",
398                  proc->pid, strerror(errno));
399                goto CloseProcess;
400            }
401
402            if (--proc->out_count == 0)
403                fdevent_del( proc->fde, FDE_WRITE );
404        }
405    }
406}
407
408
409int
410create_jdwp_connection_fd(int  pid)
411{
412    JdwpProcess*  proc = _jdwp_list.next;
413
414    D("looking for pid %d in JDWP process list\n", pid);
415    for ( ; proc != &_jdwp_list; proc = proc->next ) {
416        if (proc->pid == pid) {
417            goto FoundIt;
418        }
419    }
420    D("search failed !!\n");
421    return -1;
422
423FoundIt:
424    {
425        int  fds[2];
426
427        if (proc->out_count >= MAX_OUT_FDS) {
428            D("%s: too many pending JDWP connection for pid %d\n",
429              __FUNCTION__, pid);
430            return -1;
431        }
432
433        if (adb_socketpair(fds) < 0) {
434            D("%s: socket pair creation failed: %s\n",
435              __FUNCTION__, strerror(errno));
436            return -1;
437        }
438        D("socketpair: (%d,%d)", fds[0], fds[1]);
439
440        proc->out_fds[ proc->out_count ] = fds[1];
441        if (++proc->out_count == 1)
442            fdevent_add( proc->fde, FDE_WRITE );
443
444        return fds[0];
445    }
446}
447
448/**  VM DEBUG CONTROL SOCKET
449 **
450 **  we do implement a custom asocket to receive the data
451 **/
452
453/* name of the debug control Unix socket */
454#define  JDWP_CONTROL_NAME      "\0jdwp-control"
455#define  JDWP_CONTROL_NAME_LEN  (sizeof(JDWP_CONTROL_NAME)-1)
456
457struct JdwpControl {
458    int       listen_socket;
459    fdevent*  fde;
460};
461
462
463static void
464jdwp_control_event(int  s, unsigned events, void*  user);
465
466
467static int
468jdwp_control_init( JdwpControl*  control,
469                   const char*   sockname,
470                   int           socknamelen )
471{
472    struct sockaddr_un   addr;
473    socklen_t            addrlen;
474    int                  s;
475    int                  maxpath = sizeof(addr.sun_path);
476    int                  pathlen = socknamelen;
477
478    if (pathlen >= maxpath) {
479        D( "vm debug control socket name too long (%d extra chars)\n",
480           pathlen+1-maxpath );
481        return -1;
482    }
483
484    memset(&addr, 0, sizeof(addr));
485    addr.sun_family = AF_UNIX;
486    memcpy(addr.sun_path, sockname, socknamelen);
487
488    s = socket( AF_UNIX, SOCK_STREAM, 0 );
489    if (s < 0) {
490        D( "could not create vm debug control socket. %d: %s\n",
491           errno, strerror(errno));
492        return -1;
493    }
494
495    addrlen = (pathlen + sizeof(addr.sun_family));
496
497    if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) {
498        D( "could not bind vm debug control socket: %d: %s\n",
499           errno, strerror(errno) );
500        adb_close(s);
501        return -1;
502    }
503
504    if ( listen(s, 4) < 0 ) {
505        D("listen failed in jdwp control socket: %d: %s\n",
506          errno, strerror(errno));
507        adb_close(s);
508        return -1;
509    }
510
511    control->listen_socket = s;
512
513    control->fde = fdevent_create(s, jdwp_control_event, control);
514    if (control->fde == NULL) {
515        D( "could not create fdevent for jdwp control socket\n" );
516        adb_close(s);
517        return -1;
518    }
519
520    /* only wait for incoming connections */
521    fdevent_add(control->fde, FDE_READ);
522    close_on_exec(s);
523
524    D("jdwp control socket started (%d)\n", control->listen_socket);
525    return 0;
526}
527
528
529static void
530jdwp_control_event( int  s, unsigned  events, void*  _control )
531{
532    JdwpControl*  control = (JdwpControl*) _control;
533
534    if (events & FDE_READ) {
535        struct sockaddr   addr;
536        socklen_t         addrlen = sizeof(addr);
537        int               s = -1;
538        JdwpProcess*      proc;
539
540        do {
541            s = adb_socket_accept( control->listen_socket, &addr, &addrlen );
542            if (s < 0) {
543                if (errno == EINTR)
544                    continue;
545                if (errno == ECONNABORTED) {
546                    /* oops, the JDWP process died really quick */
547                    D("oops, the JDWP process died really quick\n");
548                    return;
549                }
550                /* the socket is probably closed ? */
551                D( "weird accept() failed on jdwp control socket: %s\n",
552                   strerror(errno) );
553                return;
554            }
555        }
556        while (s < 0);
557
558        proc = jdwp_process_alloc( s );
559        if (proc == NULL)
560            return;
561    }
562}
563
564
565static JdwpControl   _jdwp_control;
566
567/** "jdwp" local service implementation
568 ** this simply returns the list of known JDWP process pids
569 **/
570
571struct JdwpSocket {
572    asocket  socket;
573    int      pass;
574};
575
576static void
577jdwp_socket_close( asocket*  s )
578{
579    asocket*  peer = s->peer;
580
581    remove_socket(s);
582
583    if (peer) {
584        peer->peer = NULL;
585        peer->close(peer);
586    }
587    free(s);
588}
589
590static int
591jdwp_socket_enqueue( asocket*  s, apacket*  p )
592{
593    /* you can't write to this asocket */
594    put_apacket(p);
595    s->peer->close(s->peer);
596    return -1;
597}
598
599
600static void
601jdwp_socket_ready( asocket*  s )
602{
603    JdwpSocket*  jdwp = (JdwpSocket*)s;
604    asocket*     peer = jdwp->socket.peer;
605
606   /* on the first call, send the list of pids,
607    * on the second one, close the connection
608    */
609    if (jdwp->pass == 0) {
610        apacket*  p = get_apacket();
611        p->len = jdwp_process_list((char*)p->data, MAX_PAYLOAD);
612        peer->enqueue(peer, p);
613        jdwp->pass = 1;
614    }
615    else {
616        peer->close(peer);
617    }
618}
619
620asocket*
621create_jdwp_service_socket( void )
622{
623    JdwpSocket* s = reinterpret_cast<JdwpSocket*>(calloc(sizeof(*s), 1));
624
625    if (s == NULL)
626        return NULL;
627
628    install_local_socket(&s->socket);
629
630    s->socket.ready   = jdwp_socket_ready;
631    s->socket.enqueue = jdwp_socket_enqueue;
632    s->socket.close   = jdwp_socket_close;
633    s->pass           = 0;
634
635    return &s->socket;
636}
637
638/** "track-jdwp" local service implementation
639 ** this periodically sends the list of known JDWP process pids
640 ** to the client...
641 **/
642
643struct JdwpTracker {
644    asocket       socket;
645    JdwpTracker*  next;
646    JdwpTracker*  prev;
647    int           need_update;
648};
649
650static JdwpTracker   _jdwp_trackers_list;
651
652
653static void
654jdwp_process_list_updated(void)
655{
656    char             buffer[1024];
657    int              len;
658    JdwpTracker*  t = _jdwp_trackers_list.next;
659
660    len = jdwp_process_list_msg(buffer, sizeof(buffer));
661
662    for ( ; t != &_jdwp_trackers_list; t = t->next ) {
663        apacket*  p    = get_apacket();
664        asocket*  peer = t->socket.peer;
665        memcpy(p->data, buffer, len);
666        p->len = len;
667        peer->enqueue( peer, p );
668    }
669}
670
671static void
672jdwp_tracker_close( asocket*  s )
673{
674    JdwpTracker*  tracker = (JdwpTracker*) s;
675    asocket*      peer    = s->peer;
676
677    if (peer) {
678        peer->peer = NULL;
679        peer->close(peer);
680    }
681
682    remove_socket(s);
683
684    tracker->prev->next = tracker->next;
685    tracker->next->prev = tracker->prev;
686
687    free(s);
688}
689
690static void
691jdwp_tracker_ready( asocket*  s )
692{
693    JdwpTracker*  t = (JdwpTracker*) s;
694
695    if (t->need_update) {
696        apacket*  p = get_apacket();
697        t->need_update = 0;
698        p->len = jdwp_process_list_msg((char*)p->data, sizeof(p->data));
699        s->peer->enqueue(s->peer, p);
700    }
701}
702
703static int
704jdwp_tracker_enqueue( asocket*  s, apacket*  p )
705{
706    /* you can't write to this socket */
707    put_apacket(p);
708    s->peer->close(s->peer);
709    return -1;
710}
711
712
713asocket*
714create_jdwp_tracker_service_socket( void )
715{
716    JdwpTracker* t = reinterpret_cast<JdwpTracker*>(calloc(sizeof(*t), 1));
717
718    if (t == NULL)
719        return NULL;
720
721    t->next = &_jdwp_trackers_list;
722    t->prev = t->next->prev;
723
724    t->next->prev = t;
725    t->prev->next = t;
726
727    install_local_socket(&t->socket);
728
729    t->socket.ready   = jdwp_tracker_ready;
730    t->socket.enqueue = jdwp_tracker_enqueue;
731    t->socket.close   = jdwp_tracker_close;
732    t->need_update    = 1;
733
734    return &t->socket;
735}
736
737
738int
739init_jdwp(void)
740{
741    _jdwp_list.next = &_jdwp_list;
742    _jdwp_list.prev = &_jdwp_list;
743
744    _jdwp_trackers_list.next = &_jdwp_trackers_list;
745    _jdwp_trackers_list.prev = &_jdwp_trackers_list;
746
747    return jdwp_control_init( &_jdwp_control,
748                              JDWP_CONTROL_NAME,
749                              JDWP_CONTROL_NAME_LEN );
750}
751
752#endif /* !ADB_HOST */
753