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
Pabort_agent(struct ps_prochandle * P)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
Pcreate_agent(struct ps_prochandle * P)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
Pdestroy_agent(struct ps_prochandle * P)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
execute(struct ps_prochandle * P,int sysindex)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
Psyscall(struct ps_prochandle * P,sysret_t * rval,int sysindex,uint_t nargs,argdes_t * argp)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