Home | History | Annotate | Download | only in coregrind
      1 /*--------------------------------------------------------------------*/
      2 /*--- Implementation of vgdb invoker subsystem on Solaris             */
      3 /*                      via /proc filesystem and control messages. ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2014-2017 Ivo Raisr <ivosh (at) ivosh.net>
     11 
     12    This program is free software; you can redistribute it and/or
     13    modify it under the terms of the GNU General Public License as
     14    published by the Free Software Foundation; either version 2 of the
     15    License, or (at your option) any later version.
     16 
     17    This program is distributed in the hope that it will be useful, but
     18    WITHOUT ANY WARRANTY; without even the implied warranty of
     19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     20    General Public License for more details.
     21 
     22    You should have received a copy of the GNU General Public License
     23    along with this program; if not, write to the Free Software
     24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     25    02111-1307, USA.
     26 
     27    The GNU General Public License is contained in the file COPYING.
     28 */
     29 
     30 /* This module implements vgdb-invoker subsystem as per vgdb.h
     31    on Solaris. It differs significantly from the other ptrace-based
     32    implementation found in vgdb-invoker-ptrace.c. However the goal
     33    is the same - to work on the following scenario:
     34 
     35    - A valgrind process (referred to also as an inferior process)
     36      is remotely debugged with gdb.
     37    - All threads of the inferior process are stuck in blocking
     38      syscalls.
     39    - Therefore no thread can process packets received from gdb.
     40 
     41    When module vgdb.c detects this situation then it calls
     42    function invoker_invoke_gdbserver() within the context of
     43    invoke_gdbserver_in_valgrind_thread thread. The steps of
     44    interaction between vgdb and m_gdbserver module are as follows:
     45 
     46    1. Function invoker_invoke_gdbserver() attaches to the inferior
     47       process and stops all threads.
     48    2. It gets registers of the first thread and modifies them
     49       and the stack so that a call to "invoke_gdbserver" function
     50       is arranged along with a function parameter.
     51    3. Then it creates an agent thread within the inferior process
     52       with these modified registers and waits until the agent thread
     53       exits.
     54    4. Meanwhile in the inferior process function
     55       VG_(invoke_gdbserver)() is invoked within the context of the
     56       agent thread; all other threads are still stopped.
     57    5. The agent thread processes packets from gdb relayed by vgdb.
     58    6. Eventually processing is finished and the agent thread exits
     59       in function give_control_back_to_vgdb().
     60    7. vgdb then detaches from the inferior process and thus resumes
     61       all the stopped threads.
     62  */
     63 
     64 #include "vgdb.h"
     65 
     66 #include <assert.h>
     67 #include <errno.h>
     68 #include <string.h>
     69 
     70 typedef Addr CORE_ADDR;
     71 
     72 typedef struct {
     73    long cmd;
     74    union {
     75        long flags;
     76        prgregset_t regs;
     77    } arg;
     78 } ctl_t;
     79 
     80 /* Process control file /proc/<pid>/ctl.
     81    Once this file is closed, PR_RLC flag takes effect and
     82    inferior process resumes automatically. */
     83 static int ctl_fd = -1;
     84 
     85 /* Copy LEN bytes of data from vgdb memory at MYADDR
     86    to valgrind memory at MEMADDR.
     87    On failure (cannot write the valgrind memory)
     88    returns the value of errno. */
     89 static int write_memory(pid_t pid, CORE_ADDR memaddr,
     90                         const void *myaddr, size_t len)
     91 {
     92    char procname[PATH_MAX];
     93    snprintf(procname, sizeof(procname), "/proc/%d/as", pid);
     94 
     95    /* Open the process address-space file. */
     96    int as_fd = open(procname, O_WRONLY, 0);
     97    if (as_fd < 0) {
     98       int error = errno;
     99       ERROR(error, "Failed to open %s.\n", procname);
    100       return error;
    101    }
    102 
    103    if (debuglevel >= 1) {
    104       DEBUG(1, "Writing bytes '");
    105       size_t i;
    106       for (i = 0; i < len; i++)
    107          PDEBUG(1, "%02x", ((const unsigned char *) myaddr)[i]);
    108       PDEBUG(1, "' to address %#lx.\n", memaddr);
    109    }
    110 
    111    ssize_t written = pwrite(as_fd, myaddr, len, memaddr);
    112    if ((written < 0) || (written != len)) {
    113       int error = errno;
    114       ERROR(error, "Failed to write to file %s, memory block of %zu"
    115             " bytes at %#lx to %#lx.\n",
    116             procname, len, (Addr) myaddr, memaddr);
    117       close(as_fd);
    118       return error;
    119    }
    120 
    121    DEBUG(1, "Written ok.\n");
    122    close(as_fd);
    123    return 0;
    124 }
    125 
    126 /* Attaches to a process identified by pid and stops all threads. */
    127 static Bool attach(pid_t pid)
    128 {
    129    char procname[PATH_MAX];
    130    snprintf(procname, sizeof(procname), "/proc/%d/ctl", pid);
    131 
    132    DEBUG(1, "Attaching to pid %d.\n", pid);
    133 
    134    /* Open the process control file. */
    135    ctl_fd = open(procname, O_WRONLY, 0);
    136    if (ctl_fd < 0) {
    137       ERROR(errno, "Failed to open %s.\n", procname);
    138       return False;
    139    }
    140 
    141    DEBUG(1, "Setting run-on-last-close-flag (PR_RLC) to pid %d.\n", pid);
    142 
    143    /* Set run-on-last-close flag. */
    144    ctl_t ctl;
    145    ctl.cmd = PCSET;
    146    ctl.arg.flags = PR_RLC;
    147    size_t bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.flags);
    148    ssize_t written = write(ctl_fd, (void *) &ctl, bytes);
    149    if ((written < 0) || (written != bytes)) {
    150       ERROR(errno, "Failed to write to ctl_fd: PCSET + PR_RLC.\n");
    151       return False;
    152    }
    153 
    154    DEBUG(1, "Stopping process %d.\n", pid);
    155 
    156    /* Stop the whole process - all threads. */
    157    ctl.cmd = PCSTOP;
    158    bytes = sizeof(ctl.cmd);
    159    written = write(ctl_fd, (void *) &ctl, bytes);
    160    if ((written < 0) || (written != bytes)) {
    161       ERROR(errno, "Failed to write to ctl_fd: PCSTOP.\n");
    162       return False;
    163    }
    164 
    165    DEBUG(1, "Process %d stopped.\n", pid);
    166 
    167    /* Now confirm it is actually the case. */
    168    snprintf(procname, sizeof(procname), "/proc/%d/status", pid);
    169    int status_fd = open(procname, O_RDONLY, 0);
    170    if (status_fd < 0) {
    171       ERROR(errno, "Failed to open %s.\n", procname);
    172       return False;
    173    }
    174 
    175    pstatus_t pstatus;
    176    bytes = read(status_fd, &pstatus, sizeof(pstatus));
    177    if ((bytes < 0) || (bytes != sizeof(pstatus))) {
    178       ERROR(errno, "Failed to read from %s.\n", procname);
    179       close(status_fd);
    180       return False;
    181    }
    182 
    183    if (pstatus.pr_flags & PR_RLC) {
    184       DEBUG(2, "Process %d has run-on-last-close flag set. Good.\n", pid);
    185    } else {
    186       ERROR(0, "Process %d does not have run-on-last-close flag set!\n", pid);
    187       close(status_fd);
    188       return False;
    189    }
    190 
    191    if (pstatus.pr_lwp.pr_flags & PR_STOPPED) {
    192       DEBUG(3, "Process %d seems to be stopped. Good.\n", pid);
    193    } else {
    194       ERROR(0, "Process %d is not stopped!\n", pid);
    195       close(status_fd);
    196       return False;
    197    }
    198 
    199    close(status_fd);
    200    return True;
    201 }
    202 
    203 static void detach(pid_t pid)
    204 {
    205    if (ctl_fd != -1) {
    206       close(ctl_fd);
    207       ctl_fd = -1;
    208    }
    209 
    210    DEBUG(1, "Detached from pid %d.\n", pid);
    211 }
    212 
    213 /* Gets the registers of the first thread. */
    214 static Bool get_regs(pid_t pid, prgregset_t *regs)
    215 {
    216    char procname[PATH_MAX];
    217    snprintf(procname, sizeof(procname), "/proc/%d/lwp/1/lwpstatus", pid);
    218 
    219    DEBUG(1, "Getting registers from the first thread of process %d.\n", pid);
    220 
    221    /* Open the first thread's status file. */
    222    int status_fd = open(procname, O_RDONLY, 0);
    223    if (status_fd < 0) {
    224       ERROR(errno, "Failed to open file %s.\n", procname);
    225       return False;
    226    }
    227 
    228    lwpstatus_t status;
    229    ssize_t bytes = read(status_fd, &status, sizeof(status));
    230    if ((bytes < 0) || (bytes != sizeof(status))) {
    231       ERROR(errno, "Failed to read from %s.\n", procname);
    232       close(status_fd);
    233       return False;
    234    }
    235 
    236    DEBUG(3, "Registers of thread %d from process %d: ", status.pr_lwpid, pid);
    237    unsigned int i;
    238    for (i = 0; i < _NGREG; i++) {
    239       PDEBUG(3, "%u: %#lx, ", i, (unsigned long) status.pr_reg[i]);
    240    }
    241    PDEBUG(3, "\n");
    242 
    243    memcpy(regs, &status.pr_reg, sizeof(prgregset_t));
    244    close(status_fd);
    245    return True;
    246 }
    247 
    248 /* Modifies the register set so that a new stack frame is created
    249    for "invoke_gdbserver" function with an extra argument.
    250    The argument is written to the stack of the first thread.
    251  */
    252 static Bool setup_stack_frame(pid_t pid, prgregset_t *regs)
    253 {
    254    DEBUG(1, "Setting up new stack frame of process %d.\n", pid);
    255 
    256    /* A specific int value is passed to invoke_gdbserver(), to check
    257       everything goes according to the plan. */
    258    const int check = 0x8BADF00D; // ate bad food.
    259 
    260    /* A bad return address will be pushed on the stack.
    261       Function invoke_gdbserver() cannot return. If it ever returns,
    262       a NULL address pushed on the stack should ensure this is
    263       detected. */
    264    const Addr bad_return = 0;
    265 
    266 #if defined(VGA_x86)
    267    Addr sp = (*regs)[UESP];
    268 #elif defined(VGA_amd64)
    269    Addr sp = (*regs)[REG_RSP];
    270 #else
    271    I_die_here : (sp) architecture missing in vgdb-invoker-solaris.c
    272 #endif
    273 
    274    if (shared32 != NULL) {
    275       /* vgdb speaking with a 32bit executable. */
    276 #if   defined(VGA_x86) || defined(VGA_amd64)
    277       const size_t regsize = 4;
    278 
    279       /* Push check argument on the stack - according to C/ia32 ABI. */
    280       sp = sp - regsize;
    281       DEBUG(1, "Pushing check argument to process %d memory.\n", pid);
    282       assert(regsize == sizeof(check));
    283       int error = write_memory(pid, sp, &check, regsize);
    284       if (error != 0) {
    285          ERROR(error, "Failed to push check argument to process %d memory.\n",
    286                       pid);
    287          detach(pid);
    288          return False;
    289       }
    290 
    291       sp = sp - regsize;
    292       DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
    293                pid);
    294       /* Note that even for a 64 bits vgdb, only 4 bytes
    295          of NULL bad_return are written. */
    296       error = write_memory(pid, sp, &bad_return, regsize);
    297       if (error != 0) {
    298          ERROR(error, "Failed to push bad_return return address to process %d "
    299                       "memory.\n", pid);
    300          detach(pid);
    301          return False;
    302       }
    303 
    304 #if   defined(VGA_x86)
    305       /* Set EBP, ESP, EIP to invoke gdbserver.
    306          vgdb is 32bits, speaking with a 32bits process. */
    307       (*regs)[EBP] = sp; // bp set to sp
    308       (*regs)[UESP] = sp;
    309       (*regs)[EIP] = shared32->invoke_gdbserver;
    310 #elif defined(VGA_amd64)
    311       /* Set RBP, RSP, RIP to invoke gdbserver.
    312          vgdb is 64bits, speaking with a 32bits process. */
    313       (*regs)[REG_RBP] = sp; // bp set to sp
    314       (*regs)[REG_RSP] = sp;
    315       (*regs)[REG_RIP] = shared32->invoke_gdbserver;
    316 #else
    317       I_die_here : not x86 or amd64 in x86/amd64 section/
    318 #endif
    319 
    320 #else
    321       I_die_here : architecture missing in vgdb-invoker-solaris.c
    322 #endif
    323 
    324    } else if (shared64 != NULL) {
    325 #if defined(VGA_x86)
    326       assert(0); /* 64bits process with a 32bits vgdb - no way */
    327 #elif defined(VGA_amd64)
    328       /* 64bits vgdb speaking with a 64 bit process. */
    329       const int regsize = 8;
    330 
    331       /* Give check argument in rdi - according to C/amd64 ABI. */
    332       (*regs)[REG_RDI] = check;
    333 
    334       /* Push return address on stack: return to breakaddr. */
    335       sp = sp - regsize;
    336       DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
    337                pid);
    338       int error = write_memory(pid, sp, &bad_return,
    339                                sizeof(bad_return));
    340       if (error != 0) {
    341          ERROR(error, "Failed to push bad_return return address to process %d "
    342                       "memory.\n", pid);
    343          detach(pid);
    344          return False;
    345       }
    346 
    347       /* set RBP, RSP, RIP to invoke gdbserver */
    348       (*regs)[REG_RBP] = sp; // bp set to sp
    349       (*regs)[REG_RSP] = sp;
    350       (*regs)[REG_RIP] = shared64->invoke_gdbserver;
    351 #else
    352       I_die_here: architecture missing in vgdb-invoker-solaris.c
    353 #endif
    354    } else {
    355       assert(0);
    356    }
    357 
    358    DEBUG(1, "New stack frame set up for process %d.\n", pid);
    359    return True;
    360 }
    361 
    362 /* Creates and starts an agent thread within the inferior process.
    363    The agent thread is created stopped and with its held signal set
    364    (the signal mask) having all signals except SIGKILL and SIGSTOP
    365    blocked. All these signals need to remain blocked while the agent
    366    thread is running because valgrind syscall/signal machinery expects
    367    that (remember: all valgrind threads are blocked in VgTs_WaitSys
    368    - that is the reason why we are invoking the agent, after all).
    369    It is necessary to resume the agent thread afterwards.
    370  */
    371 static Bool invoke_agent(pid_t pid, prgregset_t *regs, id_t *agent_lwpid)
    372 {
    373    assert(ctl_fd != -1);
    374 
    375    DEBUG(1, "Creating an agent thread within process %d.\n", pid);
    376 
    377    /* Create the agent thread. */
    378    ctl_t ctl;
    379    ctl.cmd = PCAGENT;
    380    memcpy(&ctl.arg.regs, regs, sizeof(prgregset_t));
    381    size_t bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.regs);
    382    ssize_t written = write(ctl_fd, (void *) &ctl, bytes);
    383    if ((written < 0) || (written != bytes)) {
    384       ERROR(errno, "Failed to write to ctl_fd: PCAGENT.\n");
    385       return False;
    386    }
    387 
    388    DEBUG(1, "Obtaining agent thread lwpid for process %d.\n", pid);
    389 
    390    char procname[PATH_MAX];
    391    snprintf(procname, sizeof(procname),
    392             "/proc/%d/lwp/agent/lwpstatus", pid);
    393 
    394    int status_fd = open(procname, O_RDONLY, 0);
    395    if (status_fd < 0) {
    396       /* Operation failed but there is no way to get rid of the agent
    397          thread from outside. We are doomed... */
    398       ERROR(errno, "Failed to open file %s.\n", procname);
    399       return False;
    400    }
    401 
    402    lwpstatus_t status;
    403    bytes = read(status_fd, &status, sizeof(status));
    404    if ((bytes < 0) || (bytes != sizeof(status))) {
    405       ERROR(errno, "Failed to read from %s.\n", procname);
    406       close(status_fd);
    407       return False;
    408    }
    409 
    410    close(status_fd);
    411    *agent_lwpid = status.pr_lwpid;
    412 
    413    snprintf(procname, sizeof(procname),
    414             "/proc/%d/lwp/agent/lwpctl", pid);
    415 
    416    int agent_ctl_fd = open(procname, O_WRONLY, 0);
    417    if (agent_ctl_fd < 0) {
    418       /* Resuming failed but there is no way to get rid of the agent
    419          thread from outside. We are doomed... */
    420       ERROR(errno, "Failed to open file %s.\n", procname);
    421       return False;
    422    }
    423 
    424    DEBUG(1, "Resuming the agent thread for process %d.\n", pid);
    425 
    426    /* Resume the agent thread. */
    427    ctl.cmd = PCRUN;
    428    ctl.arg.flags = 0;
    429    bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.flags);
    430    written = write(agent_ctl_fd, (void *) &ctl, bytes);
    431    if ((written < 0) || (written != bytes)) {
    432       /* Resuming failed but there is no way to get rid of the agent
    433          thread from outside. We are doomed... */
    434       ERROR(errno, "Failed to write to agent_ctl_fd: PCRUN 0.\n");
    435       close(agent_ctl_fd);
    436       return False;
    437    }
    438 
    439    DEBUG(1, "Agent thread lwpid %d now running within process %d.\n",
    440          *agent_lwpid, pid);
    441    close(agent_ctl_fd);
    442    return True;
    443 }
    444 
    445 /* Waits until the agent thread running inside the inferior
    446    process exits. */
    447 static Bool wait_for_agent_exit(pid_t pid, id_t agent_lwpid)
    448 {
    449    char procname[PATH_MAX];
    450    snprintf(procname, sizeof(procname), "/proc/%d/lwp/agent/lwpctl", pid);
    451 
    452    int agent_ctl_fd = open(procname, O_WRONLY, 0);
    453    if (agent_ctl_fd < 0) {
    454       if (errno == ENOENT) {
    455          DEBUG(1, "Agent control file %s no longer exists. This means "
    456                "agent thread %d exited meanwhile.\n",
    457                procname, agent_lwpid);
    458          return True;
    459       }
    460       ERROR(errno, "Failed to open agent control file %s.\n", procname);
    461       return False;
    462    }
    463 
    464    DEBUG(1, "Waiting for agent thread %d to exit.\n", agent_lwpid);
    465 
    466    /* Wait until the agent thread stops. This covers also the case
    467       when the thread exited. */
    468    ctl_t ctl;
    469    ctl.cmd = PCWSTOP;
    470    size_t bytes = sizeof(ctl.cmd);
    471    ssize_t written = write(agent_ctl_fd, (void *) &ctl, bytes);
    472    if ((written < 0) || (written != bytes)) {
    473       if (errno == ENOENT) {
    474          DEBUG(1, "Agent thread lwpid %d has now exited in process %d.\n",
    475                   agent_lwpid, pid);
    476       } else {
    477          ERROR(errno, "Failed to write to agent_ctl_fd: PCWSTOP.\n");
    478          close(agent_ctl_fd);
    479          return False;
    480       }
    481    }
    482 
    483    close(agent_ctl_fd);
    484    return True;
    485 }
    486 
    487 Bool invoker_invoke_gdbserver(pid_t pid)
    488 {
    489    if (attach(pid) != True) {
    490       return False;
    491    }
    492 
    493    prgregset_t regs;
    494    if (get_regs(pid, &regs) != True) {
    495       detach(pid);
    496       return False;
    497    }
    498 
    499    if (setup_stack_frame(pid, &regs) != True) {
    500       detach(pid);
    501       return False;
    502    }
    503 
    504    id_t agent_lwpid;
    505    if (invoke_agent(pid, &regs, &agent_lwpid) != True) {
    506       detach(pid);
    507       return False;
    508    }
    509 
    510    if (wait_for_agent_exit(pid, agent_lwpid) != True) {
    511       detach(pid);
    512       return False;
    513    }
    514 
    515    detach(pid);
    516    return True;
    517 }
    518 
    519 void invoker_cleanup_restore_and_detach(void *v_pid)
    520 {
    521    detach(*(int *) v_pid);
    522 }
    523 
    524 void invoker_restrictions_msg(void)
    525 {
    526 }
    527 
    528 void invoker_valgrind_dying(void)
    529 {
    530 }
    531