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