1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright (c) 2013, Joyent Inc. All rights reserved.
  27  */
  28 
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <unistd.h>
  32 #include <ctype.h>
  33 #include <fcntl.h>
  34 #include <string.h>
  35 #include <memory.h>
  36 #include <errno.h>
  37 #include <dirent.h>
  38 #include <limits.h>
  39 #include <signal.h>
  40 #include <sys/types.h>
  41 #include <sys/uio.h>
  42 #include <sys/stat.h>
  43 #include <sys/resource.h>
  44 #include <sys/param.h>
  45 #include <sys/stack.h>
  46 #include <sys/fault.h>
  47 #include <sys/syscall.h>
  48 #include <sys/sysmacros.h>
  49 
  50 #include "libproc.h"
  51 #include "Pcontrol.h"
  52 #include "Putil.h"
  53 #include "P32ton.h"
  54 #include "Pisadep.h"
  55 
  56 extern sigset_t blockable_sigs;
  57 
  58 static void
  59 Pabort_agent(struct ps_prochandle *P)
  60 {
  61         int sysnum = P->status.pr_lwp.pr_syscall;
  62         int stop;
  63 
  64         dprintf("agent LWP is asleep in syscall %d\n", sysnum);
  65         (void) Pstop(P, 0);
  66         stop = Psysexit(P, sysnum, TRUE);
  67 
  68         if (Psetrun(P, 0, PRSABORT) == 0) {
  69                 while (Pwait(P, 0) == -1 && errno == EINTR)
  70                         continue;
  71                 (void) Psysexit(P, sysnum, stop);
  72                 dprintf("agent LWP system call aborted\n");
  73         }
  74 }
  75 
  76 /*
  77  * Create the /proc agent LWP for further operations.
  78  */
  79 int
  80 Pcreate_agent(struct ps_prochandle *P)
  81 {
  82         int fd;
  83         char pathname[PATH_MAX];
  84         char *fname;
  85         struct {
  86                 long    cmd;
  87                 prgregset_t regs;
  88         } cmd;
  89 
  90         /*
  91          * If not first reference, we already have the /proc agent LWP active.
  92          */
  93         if (P->agentcnt > 0) {
  94                 P->agentcnt++;
  95                 return (0);
  96         }
  97 
  98         /*
  99          * The agent is not available for use as a mortician or as an
 100          * obstetrician.
 101          */
 102         if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
 103             P->state == PS_IDLE) {
 104                 errno = ENOENT;
 105                 return (-1);
 106         }
 107 
 108         /*
 109          * Create the special /proc agent LWP if it doesn't already exist.
 110          * Give it the registers of the representative LWP.
 111          */
 112         (void) Pstop(P, 0);
 113         Psync(P);
 114         if (!(P->status.pr_lwp.pr_flags & PR_AGENT)) {
 115                 cmd.cmd = PCAGENT;
 116                 (void) memcpy(&cmd.regs, &P->status.pr_lwp.pr_reg[0],
 117                     sizeof (P->status.pr_lwp.pr_reg));
 118                 if (write(P->ctlfd, &cmd, sizeof (cmd)) != sizeof (cmd))
 119                         goto bad;
 120         }
 121 
 122         /* refresh the process status */
 123         (void) Pstopstatus(P, PCNULL, 0);
 124 
 125         /* open the agent LWP files */
 126         (void) snprintf(pathname, sizeof (pathname), "%s/%d/lwp/agent/",
 127             procfs_path, (int)P->pid);
 128         fname = pathname + strlen(pathname);
 129         (void) set_minfd();
 130 
 131         /*
 132          * It is difficult to know how to recover from the two errors
 133          * that follow.  The agent LWP exists and we need to kill it,
 134          * but we can't because we need it active in order to kill it.
 135          * We just hope that these failures never occur.
 136          */
 137         (void) strcpy(fname, "lwpstatus");
 138         if ((fd = open(pathname, O_RDONLY)) < 0 ||
 139             (fd = dupfd(fd, 0)) < 0)
 140                 goto bad;
 141         P->agentstatfd = fd;
 142 
 143         (void) strcpy(fname, "lwpctl");
 144         if ((fd = open(pathname, O_WRONLY)) < 0 ||
 145             (fd = dupfd(fd, 0)) < 0)
 146                 goto bad;
 147         P->agentctlfd = fd;
 148 
 149         /*
 150          * If the agent is currently asleep in a system call, attempt
 151          * to abort the system call so it's ready to serve.
 152          */
 153         if (P->status.pr_lwp.pr_flags & PR_ASLEEP) {
 154                 dprintf("Pcreate_agent: aborting agent syscall\n");
 155                 Pabort_agent(P);
 156         }
 157 
 158         /* get the agent LWP status */
 159         P->agentcnt++;
 160         if (Pstopstatus(P, PCNULL, 0) != 0) {
 161                 Pdestroy_agent(P);
 162                 return (-1);
 163         }
 164 
 165         return (0);
 166 
 167 bad:
 168         if (P->agentstatfd >= 0)
 169                 (void) close(P->agentstatfd);
 170         if (P->agentctlfd >= 0)
 171                 (void) close(P->agentctlfd);
 172         P->agentstatfd = -1;
 173         P->agentctlfd = -1;
 174         /* refresh the process status */
 175         (void) Pstopstatus(P, PCNULL, 0);
 176         return (-1);
 177 }
 178 
 179 /*
 180  * Decrement the /proc agent agent reference count.
 181  * On last reference, destroy the agent.
 182  */
 183 void
 184 Pdestroy_agent(struct ps_prochandle *P)
 185 {
 186         if (P->agentcnt > 1)
 187                 P->agentcnt--;
 188         else {
 189                 int flags;
 190 
 191                 Psync(P); /* Flush out any pending changes */
 192 
 193                 (void) Pstopstatus(P, PCNULL, 0);
 194                 flags = P->status.pr_lwp.pr_flags;
 195 
 196                 /*
 197                  * If the agent is currently asleep in a system call, attempt
 198                  * to abort the system call so we can terminate the agent.
 199                  */
 200                 if ((flags & (PR_AGENT|PR_ASLEEP)) == (PR_AGENT|PR_ASLEEP)) {
 201                         dprintf("Pdestroy_agent: aborting agent syscall\n");
 202                         Pabort_agent(P);
 203                 }
 204 
 205                 /*
 206                  * The agent itself is destroyed by forcing it to execute
 207                  * the _lwp_exit(2) system call.  Close our agent descriptors
 208                  * regardless of whether this is successful.
 209                  */
 210                 (void) pr_lwp_exit(P);
 211                 (void) close(P->agentctlfd);
 212                 (void) close(P->agentstatfd);
 213                 P->agentctlfd = -1;
 214                 P->agentstatfd = -1;
 215                 P->agentcnt = 0;
 216 
 217                 /*
 218                  * Now that (hopefully) the agent has exited, refresh the
 219                  * status: the representative LWP is no longer the agent.
 220                  */
 221                 (void) Pstopstatus(P, PCNULL, 0);
 222         }
 223 }
 224 
 225 /*
 226  * Execute the syscall instruction.
 227  */
 228 static int
 229 execute(struct ps_prochandle *P, int sysindex)
 230 {
 231         int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
 232         int washeld = FALSE;
 233         sigset_t hold;          /* mask of held signals */
 234         int cursig;
 235         struct {
 236                 long cmd;
 237                 siginfo_t siginfo;
 238         } ctl;
 239         int sentry;             /* old value of stop-on-syscall-entry */
 240 
 241         sentry = Psysentry(P, sysindex, TRUE);  /* set stop-on-syscall-entry */
 242 
 243         /*
 244          * If not already blocked, block all signals now.
 245          */
 246         if (memcmp(&P->status.pr_lwp.pr_lwphold, &blockable_sigs,
 247             sizeof (sigset_t)) != 0) {
 248                 hold = P->status.pr_lwp.pr_lwphold;
 249                 P->status.pr_lwp.pr_lwphold = blockable_sigs;
 250                 P->flags |= SETHOLD;
 251                 washeld = TRUE;
 252         }
 253 
 254         /*
 255          * If there is a current signal, remember it and cancel it.
 256          */
 257         if ((cursig = P->status.pr_lwp.pr_cursig) != 0) {
 258                 ctl.cmd = PCSSIG;
 259                 ctl.siginfo = P->status.pr_lwp.pr_info;
 260         }
 261 
 262         if (Psetrun(P, 0, PRCSIG | PRCFAULT) == -1)
 263                 goto bad;
 264 
 265         while (P->state == PS_RUN) {
 266                 (void) Pwait(P, 0);
 267         }
 268         if (P->state != PS_STOP)
 269                 goto bad;
 270 
 271         if (cursig)                             /* restore cursig */
 272                 (void) write(ctlfd, &ctl, sizeof (ctl));
 273         if (washeld) {          /* restore the signal mask if we set it */
 274                 P->status.pr_lwp.pr_lwphold = hold;
 275                 P->flags |= SETHOLD;
 276         }
 277 
 278         (void) Psysentry(P, sysindex, sentry);  /* restore sysentry stop */
 279 
 280         if (P->status.pr_lwp.pr_why  == PR_SYSENTRY &&
 281             P->status.pr_lwp.pr_what == sysindex)
 282                 return (0);
 283 bad:
 284         return (-1);
 285 }
 286 
 287 
 288 /*
 289  * Perform system call in controlled process.
 290  */
 291 int
 292 Psyscall(struct ps_prochandle *P,
 293         sysret_t *rval,         /* syscall return values */
 294         int sysindex,           /* system call index */
 295         uint_t nargs,           /* number of arguments to system call */
 296         argdes_t *argp)         /* argument descriptor array */
 297 {
 298         int agent_created = FALSE;
 299         pstatus_t save_pstatus;
 300         argdes_t *adp;                  /* pointer to argument descriptor */
 301         int i;                          /* general index value */
 302         int model;                      /* data model */
 303         int error = 0;                  /* syscall errno */
 304         int Perr = 0;                   /* local error number */
 305         int sexit;                      /* old value of stop-on-syscall-exit */
 306         prgreg_t sp;                    /* adjusted stack pointer */
 307         prgreg_t ap;                    /* adjusted argument pointer */
 308         sigset_t unblock;
 309 
 310         (void) sigprocmask(SIG_BLOCK, &blockable_sigs, &unblock);
 311 
 312         rval->sys_rval1 = 0;         /* initialize return values */
 313         rval->sys_rval2 = 0;
 314 
 315         if (sysindex <= 0 || sysindex > PRMAXSYS || nargs > MAXARGS)
 316                 goto bad1;      /* programming error */
 317 
 318         if (P->state == PS_DEAD || P->state == PS_UNDEAD || P->state == PS_IDLE)
 319                 goto bad1;      /* dead processes can't perform system calls */
 320 
 321         model = P->status.pr_dmodel;
 322 #ifndef _LP64
 323         /* We must be a 64-bit process to deal with a 64-bit process */
 324         if (model == PR_MODEL_LP64)
 325                 goto bad9;
 326 #endif
 327 
 328         /*
 329          * Create the /proc agent LWP in the process to do all the work.
 330          * (It may already exist; nested create/destroy is permitted
 331          * by virtue of the reference count.)
 332          */
 333         if (Pcreate_agent(P) != 0)
 334                 goto bad8;
 335 
 336         /*
 337          * Save agent's status to restore on exit.
 338          */
 339         agent_created = TRUE;
 340         save_pstatus = P->status;
 341 
 342         if (P->state != PS_STOP ||           /* check state of LWP */
 343             (P->status.pr_flags & PR_ASLEEP))
 344                 goto bad2;
 345 
 346         if (Pscantext(P))                       /* bad text ? */
 347                 goto bad3;
 348 
 349         /*
 350          * Validate arguments and compute the stack frame parameters.
 351          * Begin with the current stack pointer.
 352          */
 353 #ifdef _LP64
 354         if (model == PR_MODEL_LP64) {
 355                 sp = P->status.pr_lwp.pr_reg[R_SP] + STACK_BIAS;
 356 #if defined(__amd64)
 357                 /*
 358                  * To offset the expense of computerised subtraction, the AMD64
 359                  * ABI allows a process the use of a 128-byte area beyond the
 360                  * location pointed to by %rsp.  We must advance the agent's
 361                  * stack pointer by at least the size of this region or else it
 362                  * may corrupt this temporary storage.
 363                  */
 364                 sp -= STACK_RESERVE64;
 365 #endif
 366                 sp = PSTACK_ALIGN64(sp);
 367         } else {
 368 #endif
 369                 sp = (uint32_t)P->status.pr_lwp.pr_reg[R_SP];
 370                 sp = PSTACK_ALIGN32(sp);
 371 #ifdef _LP64
 372         }
 373 #endif
 374 
 375         /*
 376          * For each AT_BYREF argument, compute the necessary
 377          * stack space and the object's stack address.
 378          */
 379         for (i = 0, adp = argp; i < nargs; i++, adp++) {
 380                 rval->sys_rval1 = i;         /* in case of error */
 381                 switch (adp->arg_type) {
 382                 default:                        /* programming error */
 383                         goto bad4;
 384                 case AT_BYVAL:                  /* simple argument */
 385                         break;
 386                 case AT_BYREF:                  /* must allocate space */
 387                         switch (adp->arg_inout) {
 388                         case AI_INPUT:
 389                         case AI_OUTPUT:
 390                         case AI_INOUT:
 391                                 if (adp->arg_object == NULL)
 392                                         goto bad5;      /* programming error */
 393                                 break;
 394                         default:                /* programming error */
 395                                 goto bad6;
 396                         }
 397                         /* allocate stack space for BYREF argument */
 398                         if (adp->arg_size == 0 || adp->arg_size > MAXARGL)
 399                                 goto bad7;      /* programming error */
 400 #ifdef _LP64
 401                         if (model == PR_MODEL_LP64)
 402                                 sp = PSTACK_ALIGN64(sp - adp->arg_size);
 403                         else
 404 #endif
 405                                 sp = PSTACK_ALIGN32(sp - adp->arg_size);
 406                         adp->arg_value = sp; /* stack address for object */
 407                         break;
 408                 }
 409         }
 410         rval->sys_rval1 = 0;                 /* in case of error */
 411         /*
 412          * Point of no return.
 413          * Perform the system call entry, adjusting %sp.
 414          * This moves the LWP to the stopped-on-syscall-entry state
 415          * just before the arguments to the system call are fetched.
 416          */
 417         ap = Psyscall_setup(P, nargs, sysindex, sp);
 418         P->flags |= SETREGS; /* set registers before continuing */
 419         dprintf("Psyscall(): execute(sysindex = %d)\n", sysindex);
 420 
 421         /*
 422          * Execute the syscall instruction and stop on syscall entry.
 423          */
 424         if (execute(P, sysindex) != 0 ||
 425             (!Pissyscall(P, P->status.pr_lwp.pr_reg[R_PC]) &&
 426             !Pissyscall_prev(P, P->status.pr_lwp.pr_reg[R_PC], NULL)))
 427                 goto bad10;
 428 
 429         dprintf("Psyscall(): copying arguments\n");
 430 
 431         /*
 432          * The LWP is stopped at syscall entry.
 433          * Copy objects to stack frame for each argument.
 434          */
 435         for (i = 0, adp = argp; i < nargs; i++, adp++) {
 436                 rval->sys_rval1 = i;         /* in case of error */
 437                 if (adp->arg_type != AT_BYVAL &&
 438                     adp->arg_inout != AI_OUTPUT) {
 439                         /* copy input byref parameter to process */
 440                         if (Pwrite(P, adp->arg_object, adp->arg_size,
 441                             (uintptr_t)adp->arg_value) != adp->arg_size)
 442                                 goto bad17;
 443                 }
 444         }
 445         rval->sys_rval1 = 0;                 /* in case of error */
 446         if (Psyscall_copyinargs(P, nargs, argp, ap) != 0)
 447                 goto bad18;
 448 
 449         /*
 450          * Complete the system call.
 451          * This moves the LWP to the stopped-on-syscall-exit state.
 452          */
 453         dprintf("Psyscall(): set running at sysentry\n");
 454 
 455         sexit = Psysexit(P, sysindex, TRUE);    /* catch this syscall exit */
 456         do {
 457                 if (Psetrun(P, 0, 0) == -1)
 458                         goto bad21;
 459                 while (P->state == PS_RUN)
 460                         (void) Pwait(P, 0);
 461         } while (P->state == PS_STOP && P->status.pr_lwp.pr_why != PR_SYSEXIT);
 462         (void) Psysexit(P, sysindex, sexit);    /* restore original setting */
 463 
 464         /*
 465          * If the system call was _lwp_exit(), we expect that our last call
 466          * to Pwait() will yield ENOENT because the LWP no longer exists.
 467          */
 468         if (sysindex == SYS_lwp_exit && errno == ENOENT) {
 469                 dprintf("Psyscall(): _lwp_exit successful\n");
 470                 rval->sys_rval1 = rval->sys_rval2 = 0;
 471                 goto out;
 472         }
 473 
 474         if (P->state != PS_STOP || P->status.pr_lwp.pr_why != PR_SYSEXIT)
 475                 goto bad22;
 476 
 477         if (P->status.pr_lwp.pr_what != sysindex)
 478                 goto bad23;
 479 
 480         if (!Pissyscall_prev(P, P->status.pr_lwp.pr_reg[R_PC], NULL)) {
 481                 dprintf("Pissyscall_prev() failed\n");
 482                 goto bad24;
 483         }
 484 
 485         dprintf("Psyscall(): caught at sysexit\n");
 486 
 487         /*
 488          * For each argument.
 489          */
 490         for (i = 0, adp = argp; i < nargs; i++, adp++) {
 491                 rval->sys_rval1 = i;         /* in case of error */
 492                 if (adp->arg_type != AT_BYVAL &&
 493                     adp->arg_inout != AI_INPUT) {
 494                         /* copy output byref parameter from process */
 495                         if (Pread(P, adp->arg_object, adp->arg_size,
 496                             (uintptr_t)adp->arg_value) != adp->arg_size)
 497                                 goto bad25;
 498                 }
 499         }
 500 
 501         if (Psyscall_copyoutargs(P, nargs, argp, ap) != 0)
 502                 goto bad26;
 503 
 504         /*
 505          * Get the return values from the syscall.
 506          */
 507         if (P->status.pr_lwp.pr_errno) {     /* error return */
 508                 error = P->status.pr_lwp.pr_errno;
 509                 rval->sys_rval1 = -1L;
 510                 rval->sys_rval2 = -1L;
 511                 dprintf("Psyscall(%d) fails with errno %d\n",
 512                     sysindex, error);
 513         } else {                                /* normal return */
 514                 rval->sys_rval1 = P->status.pr_lwp.pr_rval1;
 515                 rval->sys_rval2 = P->status.pr_lwp.pr_rval2;
 516                 dprintf("Psyscall(%d) returns 0x%lx 0x%lx\n", sysindex,
 517                     P->status.pr_lwp.pr_rval1, P->status.pr_lwp.pr_rval2);
 518         }
 519 
 520         goto out;
 521 
 522 bad26:  Perr++;
 523 bad25:  Perr++;
 524 bad24:  Perr++;
 525 bad23:  Perr++;
 526 bad22:  Perr++;
 527 bad21:  Perr++;
 528         Perr++;
 529         Perr++;
 530 bad18:  Perr++;
 531 bad17:  Perr++;
 532         Perr++;
 533         Perr++;
 534         Perr++;
 535         Perr++;
 536         Perr++;
 537         Perr++;
 538 bad10:  Perr++;
 539 bad9:   Perr++;
 540 bad8:   Perr++;
 541 bad7:   Perr++;
 542 bad6:   Perr++;
 543 bad5:   Perr++;
 544 bad4:   Perr++;
 545 bad3:   Perr++;
 546 bad2:   Perr++;
 547 bad1:   Perr++;
 548         error = -1;
 549         dprintf("Psyscall(%d) fails with local error %d\n", sysindex, Perr);
 550 
 551 out:
 552         /*
 553          * Destroy the /proc agent LWP now (or just bump down the ref count).
 554          */
 555         if (agent_created) {
 556                 if (P->state != PS_UNDEAD) {
 557                         P->status = save_pstatus;
 558                         P->flags |= SETREGS;
 559                         Psync(P);
 560                 }
 561                 Pdestroy_agent(P);
 562         }
 563 
 564         (void) sigprocmask(SIG_SETMASK, &unblock, NULL);
 565         return (error);
 566 }