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 } 567