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 }