This source file includes following definitions.
- systrace_lock
- systrace_unlock
- systracef_read
- systracef_write
- systracef_ioctl
- systracef_poll
- systracef_kqfilter
- systracef_stat
- systracef_close
- systraceattach
- systraceopen
- systraceclose
- systraceread
- systracewrite
- systraceioctl
- systracepoll
- systrace_wakeup
- systrace_find
- systrace_exit
- systrace_fork
- systrace_redirect
- systrace_seteuid
- systrace_setegid
- systrace_answer
- systrace_setscriptname
- systrace_inject
- systrace_prepinject
- systrace_policy
- systrace_processready
- systrace_getcwd
- systrace_io
- systrace_attach
- systrace_execve0
- systrace_execve1
- systrace_preprepl
- systrace_replace
- systrace_fname
- systrace_replacefree
- systrace_scriptname
- systrace_namei
- systrace_findpid
- systrace_detach
- systrace_closepolicy
- systrace_insert_process
- systrace_newpolicy
- systrace_msg_ask
- systrace_msg_result
- systrace_msg_emul
- systrace_msg_ugid
- systrace_make_msg
- systrace_msg_child
- systrace_msg_policyfree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/tree.h>
34 #include <sys/malloc.h>
35 #include <sys/syscall.h>
36 #include <sys/vnode.h>
37 #include <sys/errno.h>
38 #include <sys/conf.h>
39 #include <sys/device.h>
40 #include <sys/proc.h>
41 #include <sys/file.h>
42 #include <sys/filedesc.h>
43 #include <sys/filio.h>
44 #include <sys/signalvar.h>
45 #include <sys/rwlock.h>
46 #include <sys/pool.h>
47 #include <sys/mount.h>
48 #include <sys/namei.h>
49 #include <sys/poll.h>
50 #include <sys/ptrace.h>
51
52 #include <compat/common/compat_util.h>
53
54 #include <dev/systrace.h>
55
56 void systraceattach(int);
57
58 int systraceopen(dev_t, int, int, struct proc *);
59 int systraceclose(dev_t, int, int, struct proc *);
60 int systraceread(dev_t, struct uio *, int);
61 int systracewrite(dev_t, struct uio *, int);
62 int systraceioctl(dev_t, u_long, caddr_t, int, struct proc *);
63 int systracepoll(dev_t, int, struct proc *);
64
65 uid_t systrace_seteuid(struct proc *, uid_t);
66 gid_t systrace_setegid(struct proc *, gid_t);
67 int systracef_read(struct file *, off_t *, struct uio *, struct ucred *);
68 int systracef_write(struct file *, off_t *, struct uio *, struct ucred *);
69 int systracef_ioctl(struct file *, u_long, caddr_t, struct proc *p);
70 int systracef_poll(struct file *, int, struct proc *);
71 int systracef_kqfilter(struct file *, struct knote *);
72 int systracef_stat(struct file *, struct stat *, struct proc *);
73 int systracef_close(struct file *, struct proc *);
74
75 struct str_policy {
76 TAILQ_ENTRY(str_policy) next;
77
78 int nr;
79
80 struct emul *emul;
81
82 int refcount;
83
84 int nsysent;
85 u_char *sysent;
86 };
87
88 struct str_inject {
89 caddr_t kaddr;
90 caddr_t uaddr;
91 size_t len;
92 };
93
94 #define STR_PROC_ONQUEUE 0x01
95 #define STR_PROC_WAITANSWER 0x02
96 #define STR_PROC_SYSCALLRES 0x04
97 #define STR_PROC_REPORT 0x08
98 #define STR_PROC_NEEDSEQNR 0x10
99 #define STR_PROC_SETEUID 0x20
100 #define STR_PROC_SETEGID 0x40
101
102 struct str_process {
103 TAILQ_ENTRY(str_process) next;
104 TAILQ_ENTRY(str_process) msg_next;
105
106 struct proc *proc;
107 pid_t pid;
108
109 struct fsystrace *parent;
110 struct str_policy *policy;
111
112 struct systrace_replace *replace;
113 char *fname[SYSTR_MAXFNAME];
114 size_t nfname;
115
116 int flags;
117 short answer;
118 short error;
119 u_int16_t seqnr;
120
121 uid_t seteuid;
122 uid_t saveuid;
123 gid_t setegid;
124 gid_t savegid;
125
126 int isscript;
127 char scriptname[MAXPATHLEN];
128
129 struct str_message msg;
130
131 caddr_t sg;
132 struct str_inject injects[SYSTR_MAXINJECTS];
133 int injectind;
134 };
135
136 struct rwlock systrace_lck;
137
138 static __inline void
139 systrace_lock(void)
140 {
141 rw_enter_write(&systrace_lck);
142 }
143
144 static __inline void
145 systrace_unlock(void)
146 {
147 rw_exit_write(&systrace_lck);
148 }
149
150
151
152 int systrace_attach(struct fsystrace *, pid_t);
153 int systrace_detach(struct str_process *);
154 int systrace_answer(struct str_process *, struct systrace_answer *);
155 int systrace_setscriptname(struct str_process *,
156 struct systrace_scriptname *);
157 int systrace_prepinject(struct str_process *, struct systrace_inject *);
158 int systrace_inject(struct str_process *, int);
159 int systrace_io(struct str_process *, struct systrace_io *);
160 int systrace_policy(struct fsystrace *, struct systrace_policy *);
161 int systrace_preprepl(struct str_process *, struct systrace_replace *);
162 int systrace_replace(struct str_process *, size_t, register_t []);
163 int systrace_getcwd(struct fsystrace *, struct str_process *);
164 int systrace_fname(struct str_process *, caddr_t, size_t);
165 void systrace_replacefree(struct str_process *);
166
167 int systrace_processready(struct str_process *);
168 struct proc *systrace_find(struct str_process *);
169 struct str_process *systrace_findpid(struct fsystrace *fst, pid_t pid);
170 void systrace_wakeup(struct fsystrace *);
171 void systrace_closepolicy(struct fsystrace *, struct str_policy *);
172 int systrace_insert_process(struct fsystrace *, struct proc *);
173 struct str_policy *systrace_newpolicy(struct fsystrace *, int);
174 int systrace_msg_child(struct fsystrace *, struct str_process *, pid_t);
175 int systrace_msg_policyfree(struct fsystrace *, struct str_policy *);
176 int systrace_msg_ask(struct fsystrace *, struct str_process *,
177 int, size_t, register_t []);
178 int systrace_msg_result(struct fsystrace *, struct str_process *,
179 int, int, size_t, register_t [], register_t []);
180 int systrace_msg_emul(struct fsystrace *, struct str_process *);
181 int systrace_msg_ugid(struct fsystrace *, struct str_process *);
182 int systrace_make_msg(struct str_process *, int);
183
184 static struct fileops systracefops = {
185 systracef_read,
186 systracef_write,
187 systracef_ioctl,
188 systracef_poll,
189 systracef_kqfilter,
190 systracef_stat,
191 systracef_close
192 };
193
194 struct pool systr_proc_pl;
195 struct pool systr_policy_pl;
196
197 int systrace_debug = 0;
198
199 #define DPRINTF(y) if (systrace_debug) printf y;
200
201
202 int
203 systracef_read(fp, poff, uio, cred)
204 struct file *fp;
205 off_t *poff;
206 struct uio *uio;
207 struct ucred *cred;
208 {
209 struct fsystrace *fst = (struct fsystrace *)fp->f_data;
210 struct str_process *process;
211 int error = 0;
212
213 if (uio->uio_resid != sizeof(struct str_message))
214 return (EINVAL);
215
216 again:
217 systrace_lock();
218 rw_enter_write(&fst->lock);
219 systrace_unlock();
220 if ((process = TAILQ_FIRST(&fst->messages)) != NULL) {
221 error = uiomove((caddr_t)&process->msg,
222 sizeof(struct str_message), uio);
223 if (!error) {
224 TAILQ_REMOVE(&fst->messages, process, msg_next);
225 CLR(process->flags, STR_PROC_ONQUEUE);
226
227 if (SYSTR_MSG_NOPROCESS(process))
228 pool_put(&systr_proc_pl, process);
229
230 }
231 } else if (TAILQ_FIRST(&fst->processes) == NULL) {
232
233 ;
234 } else {
235 if (fp->f_flag & FNONBLOCK)
236 error = EAGAIN;
237 else {
238 rw_exit_write(&fst->lock);
239 error = tsleep(fst, PWAIT|PCATCH, "systrrd", 0);
240 if (error)
241 goto out;
242 goto again;
243 }
244
245 }
246
247 rw_exit_write(&fst->lock);
248 out:
249 return (error);
250 }
251
252
253 int
254 systracef_write(fp, poff, uio, cred)
255 struct file *fp;
256 off_t *poff;
257 struct uio *uio;
258 struct ucred *cred;
259 {
260 return (EIO);
261 }
262
263 #define POLICY_VALID(x) ((x) == SYSTR_POLICY_PERMIT || \
264 (x) == SYSTR_POLICY_ASK || \
265 (x) == SYSTR_POLICY_NEVER)
266
267
268 int
269 systracef_ioctl(fp, cmd, data, p)
270 struct file *fp;
271 u_long cmd;
272 caddr_t data;
273 struct proc *p;
274 {
275 int ret = 0;
276 struct fsystrace *fst = (struct fsystrace *)fp->f_data;
277 struct filedesc *fdp;
278 struct str_process *strp;
279 pid_t pid = 0;
280
281 switch (cmd) {
282 case FIONBIO:
283 case FIOASYNC:
284 return (0);
285
286 case STRIOCDETACH:
287 case STRIOCREPORT:
288 pid = *(pid_t *)data;
289 if (!pid)
290 ret = EINVAL;
291 break;
292 case STRIOCANSWER:
293 pid = ((struct systrace_answer *)data)->stra_pid;
294 if (!pid)
295 ret = EINVAL;
296 break;
297 case STRIOCIO:
298 pid = ((struct systrace_io *)data)->strio_pid;
299 if (!pid)
300 ret = EINVAL;
301 break;
302 case STRIOCSCRIPTNAME:
303 pid = ((struct systrace_scriptname *)data)->sn_pid;
304 if (!pid)
305 ret = EINVAL;
306 break;
307 case STRIOCINJECT:
308 pid = ((struct systrace_inject *)data)->stri_pid;
309 if (!pid)
310 ret = EINVAL;
311 break;
312 case STRIOCGETCWD:
313 pid = *(pid_t *)data;
314 if (!pid)
315 ret = EINVAL;
316 break;
317 case STRIOCATTACH:
318 case STRIOCRESCWD:
319 case STRIOCPOLICY:
320 break;
321 case STRIOCREPLACE:
322 pid = ((struct systrace_replace *)data)->strr_pid;
323 if (!pid)
324 ret = EINVAL;
325 break;
326 default:
327 ret = EINVAL;
328 break;
329 }
330
331 if (ret)
332 return (ret);
333
334 systrace_lock();
335 rw_enter_write(&fst->lock);
336 systrace_unlock();
337 if (pid) {
338 strp = systrace_findpid(fst, pid);
339 if (strp == NULL) {
340 ret = ESRCH;
341 goto unlock;
342 }
343 }
344
345 switch (cmd) {
346 case STRIOCATTACH:
347 pid = *(pid_t *)data;
348 if (!pid)
349 ret = EINVAL;
350 else
351 ret = systrace_attach(fst, pid);
352 DPRINTF(("%s: attach to %u: %d\n", __func__, pid, ret));
353 break;
354 case STRIOCDETACH:
355 ret = systrace_detach(strp);
356 break;
357 case STRIOCREPORT:
358 SET(strp->flags, STR_PROC_REPORT);
359 break;
360 case STRIOCANSWER:
361 ret = systrace_answer(strp, (struct systrace_answer *)data);
362 break;
363 case STRIOCIO:
364 ret = systrace_io(strp, (struct systrace_io *)data);
365 break;
366 case STRIOCSCRIPTNAME:
367 ret = systrace_setscriptname(strp,
368 (struct systrace_scriptname *)data);
369 break;
370 case STRIOCINJECT:
371 ret = systrace_prepinject(strp, (struct systrace_inject *)data);
372 break;
373 case STRIOCPOLICY:
374 ret = systrace_policy(fst, (struct systrace_policy *)data);
375 break;
376 case STRIOCREPLACE:
377 ret = systrace_preprepl(strp, (struct systrace_replace *)data);
378 break;
379 case STRIOCRESCWD:
380 if (!fst->fd_pid) {
381 ret = EINVAL;
382 break;
383 }
384 fdp = p->p_fd;
385
386
387 if (fdp->fd_cdir)
388 vrele(fdp->fd_cdir);
389 if (fdp->fd_rdir)
390 vrele(fdp->fd_rdir);
391
392 fdp->fd_cdir = fst->fd_cdir;
393 fdp->fd_rdir = fst->fd_rdir;
394
395 fst->fd_pid = 0;
396 fst->fd_cdir = fst->fd_rdir = NULL;
397 break;
398 case STRIOCGETCWD:
399 ret = systrace_getcwd(fst, strp);
400 break;
401 default:
402 ret = EINVAL;
403 break;
404 }
405
406 unlock:
407 rw_exit_write(&fst->lock);
408 return (ret);
409 }
410
411
412 int
413 systracef_poll(fp, events, p)
414 struct file *fp;
415 int events;
416 struct proc *p;
417 {
418 struct fsystrace *fst = (struct fsystrace *)fp->f_data;
419 int revents = 0;
420
421 if ((events & (POLLIN | POLLRDNORM)) == 0)
422 return (0);
423
424 systrace_lock();
425 rw_enter_write(&fst->lock);
426 systrace_unlock();
427 if (!TAILQ_EMPTY(&fst->messages))
428 revents = events & (POLLIN | POLLRDNORM);
429 else
430 selrecord(p, &fst->si);
431 rw_exit_write(&fst->lock);
432
433 return (revents);
434 }
435
436
437 int
438 systracef_kqfilter(fp, kn)
439 struct file *fp;
440 struct knote *kn;
441 {
442 return (1);
443 }
444
445
446 int
447 systracef_stat(fp, sb, p)
448 struct file *fp;
449 struct stat *sb;
450 struct proc *p;
451 {
452 return (EOPNOTSUPP);
453 }
454
455
456 int
457 systracef_close(fp, p)
458 struct file *fp;
459 struct proc *p;
460 {
461 struct fsystrace *fst = (struct fsystrace *)fp->f_data;
462 struct str_process *strp;
463 struct str_policy *strpol;
464
465 systrace_lock();
466 rw_enter_write(&fst->lock);
467 systrace_unlock();
468
469
470 for (strp = TAILQ_FIRST(&fst->processes); strp;
471 strp = TAILQ_FIRST(&fst->processes)) {
472 struct proc *q = strp->proc;
473
474 systrace_detach(strp);
475 psignal(q, SIGKILL);
476 }
477
478
479 for (strp = TAILQ_FIRST(&fst->messages); strp;
480 strp = TAILQ_FIRST(&fst->messages)) {
481 TAILQ_REMOVE(&fst->messages, strp, msg_next);
482 pool_put(&systr_proc_pl, strp);
483 }
484
485
486 for (strpol = TAILQ_FIRST(&fst->policies); strpol;
487 strpol = TAILQ_FIRST(&fst->policies))
488 systrace_closepolicy(fst, strpol);
489
490
491 if (fst->fd_cdir)
492 vrele(fst->fd_cdir);
493 if (fst->fd_rdir)
494 vrele(fst->fd_rdir);
495 rw_exit_write(&fst->lock);
496
497 FREE(fp->f_data, M_XDATA);
498 fp->f_data = NULL;
499
500 return (0);
501 }
502
503 void
504 systraceattach(int n)
505 {
506 pool_init(&systr_proc_pl, sizeof(struct str_process), 0, 0, 0,
507 "strprocpl", NULL);
508 pool_init(&systr_policy_pl, sizeof(struct str_policy), 0, 0, 0,
509 "strpolpl", NULL);
510 rw_init(&systrace_lck, "systrace");
511 }
512
513 int
514 systraceopen(dev, flag, mode, p)
515 dev_t dev;
516 int flag;
517 int mode;
518 struct proc *p;
519 {
520 return (0);
521 }
522
523 int
524 systraceclose(dev, flag, mode, p)
525 dev_t dev;
526 int flag;
527 int mode;
528 struct proc *p;
529 {
530 return (0);
531 }
532
533 int
534 systraceread(dev, uio, ioflag)
535 dev_t dev;
536 struct uio *uio;
537 int ioflag;
538 {
539 return (EIO);
540 }
541
542 int
543 systracewrite(dev, uio, ioflag)
544 dev_t dev;
545 struct uio *uio;
546 int ioflag;
547 {
548 return (EIO);
549 }
550
551 int
552 systraceioctl(dev, cmd, data, flag, p)
553 dev_t dev;
554 u_long cmd;
555 caddr_t data;
556 int flag;
557 struct proc *p;
558 {
559 struct file *f;
560 struct fsystrace *fst = NULL;
561 int fd, error;
562
563 switch (cmd) {
564 case STRIOCCLONE:
565 MALLOC(fst, struct fsystrace *, sizeof(struct fsystrace),
566 M_XDATA, M_WAITOK);
567
568 memset(fst, 0, sizeof(struct fsystrace));
569 rw_init(&fst->lock, "systrace");
570 TAILQ_INIT(&fst->processes);
571 TAILQ_INIT(&fst->messages);
572 TAILQ_INIT(&fst->policies);
573
574 if (suser(p, 0) == 0)
575 fst->issuser = 1;
576 fst->p_ruid = p->p_cred->p_ruid;
577 fst->p_rgid = p->p_cred->p_rgid;
578
579 error = falloc(p, &f, &fd);
580 if (error) {
581 FREE(fst, M_XDATA);
582 return (error);
583 }
584 f->f_flag = FREAD | FWRITE;
585 f->f_type = DTYPE_SYSTRACE;
586 f->f_ops = &systracefops;
587 f->f_data = (caddr_t) fst;
588 *(int *)data = fd;
589 FILE_SET_MATURE(f);
590 break;
591 default:
592 error = EINVAL;
593 break;
594 }
595 return (error);
596 }
597
598 int
599 systracepoll(dev, events, p)
600 dev_t dev;
601 int events;
602 struct proc *p;
603 {
604 return (seltrue(dev, events, p));
605 }
606
607 void
608 systrace_wakeup(struct fsystrace *fst)
609 {
610 wakeup((caddr_t)fst);
611 selwakeup(&fst->si);
612 }
613
614 struct proc *
615 systrace_find(struct str_process *strp)
616 {
617 struct proc *proc;
618
619 if ((proc = pfind(strp->pid)) == NULL)
620 return (NULL);
621
622 if (proc != strp->proc)
623 return (NULL);
624
625 if (!ISSET(proc->p_flag, P_SYSTRACE))
626 return (NULL);
627
628 return (proc);
629 }
630
631 void
632 systrace_exit(struct proc *proc)
633 {
634 struct str_process *strp;
635 struct fsystrace *fst;
636
637 systrace_lock();
638 strp = proc->p_systrace;
639 if (strp != NULL) {
640 fst = strp->parent;
641 rw_enter_write(&fst->lock);
642 systrace_unlock();
643
644
645 systrace_msg_child(fst, strp, -1);
646
647 systrace_detach(strp);
648 rw_exit_write(&fst->lock);
649 } else
650 systrace_unlock();
651 atomic_clearbits_int(&proc->p_flag, P_SYSTRACE);
652 }
653
654 void
655 systrace_fork(struct proc *oldproc, struct proc *p)
656 {
657 struct str_process *oldstrp, *strp;
658 struct fsystrace *fst;
659
660 systrace_lock();
661 oldstrp = oldproc->p_systrace;
662 if (oldstrp == NULL) {
663 systrace_unlock();
664 return;
665 }
666
667 fst = oldstrp->parent;
668 rw_enter_write(&fst->lock);
669 systrace_unlock();
670
671 if (systrace_insert_process(fst, p))
672 goto out;
673 if ((strp = systrace_findpid(fst, p->p_pid)) == NULL)
674 panic("systrace_fork");
675
676
677 if ((strp->policy = oldstrp->policy) != NULL)
678 strp->policy->refcount++;
679
680
681 systrace_msg_child(fst, oldstrp, p->p_pid);
682 out:
683 rw_exit_write(&fst->lock);
684 }
685
686 #define REACQUIRE_LOCK do { \
687 systrace_lock(); \
688 strp = p->p_systrace; \
689 if (strp == NULL) { \
690 systrace_unlock(); \
691 return (error); \
692 } \
693 fst = strp->parent; \
694 rw_enter_write(&fst->lock); \
695 systrace_unlock(); \
696 } while (0)
697
698 int
699 systrace_redirect(int code, struct proc *p, void *v, register_t *retval)
700 {
701 struct sysent *callp;
702 struct str_process *strp;
703 struct str_policy *strpolicy;
704 struct fsystrace *fst = NULL;
705 struct emul *oldemul;
706 struct pcred *pc;
707 uid_t olduid;
708 gid_t oldgid;
709 int policy, error = 0, report = 0, maycontrol = 0, issuser = 0;
710
711 systrace_lock();
712 strp = p->p_systrace;
713 if (strp == NULL) {
714 systrace_unlock();
715 return (EINVAL);
716 }
717
718 if (code < 0 || code >= p->p_emul->e_nsysent) {
719 systrace_unlock();
720 return (EINVAL);
721 }
722
723 KASSERT(strp->proc == p);
724
725 fst = strp->parent;
726
727 rw_enter_write(&fst->lock);
728 systrace_unlock();
729
730
731
732
733
734
735
736
737 if (fst->issuser) {
738 maycontrol = 1;
739 issuser = 1;
740 } else if (!ISSET(p->p_flag, P_SUGID) &&
741 !ISSET(p->p_flag, P_SUGIDEXEC)) {
742 maycontrol = fst->p_ruid == p->p_cred->p_ruid &&
743 fst->p_rgid == p->p_cred->p_rgid;
744 }
745
746 if (!maycontrol) {
747 policy = SYSTR_POLICY_PERMIT;
748 } else {
749
750 if ((strpolicy = strp->policy) == NULL)
751 policy = SYSTR_POLICY_ASK;
752 else {
753 if (code >= strpolicy->nsysent)
754 policy = SYSTR_POLICY_NEVER;
755 else
756 policy = strpolicy->sysent[code];
757 }
758 }
759
760 callp = p->p_emul->e_sysent + code;
761
762
763 if (policy != SYSTR_POLICY_ASK) {
764 if (policy != SYSTR_POLICY_PERMIT) {
765 if (policy > 0)
766 error = policy;
767 else
768 error = EPERM;
769 }
770 systrace_replacefree(strp);
771 rw_exit_write(&fst->lock);
772 if (policy == SYSTR_POLICY_PERMIT)
773 error = (*callp->sy_call)(p, v, retval);
774 return (error);
775 }
776
777
778
779
780
781
782 systrace_inject(strp, 0 );
783 strp->sg = stackgap_init(p->p_emul);
784
785
786 error = systrace_msg_ask(fst, strp, code, callp->sy_argsize, v);
787
788
789 if (error)
790 return (error);
791
792
793 systrace_lock();
794 if ((strp = p->p_systrace) == NULL) {
795 systrace_unlock();
796 return (error);
797 }
798
799 fst = strp->parent;
800 rw_enter_write(&fst->lock);
801 systrace_unlock();
802
803 if (strp->answer == SYSTR_POLICY_NEVER) {
804 error = strp->error;
805 systrace_replacefree(strp);
806 goto out_unlock;
807 }
808
809 if (ISSET(strp->flags, STR_PROC_SYSCALLRES)) {
810 CLR(strp->flags, STR_PROC_SYSCALLRES);
811 report = 1;
812 }
813
814 error = systrace_inject(strp, 1);
815
816 if (!error && strp->replace != NULL)
817 error = systrace_replace(strp, callp->sy_argsize, v);
818 if (error)
819 goto out_unlock;
820
821 oldemul = p->p_emul;
822 pc = p->p_cred;
823 olduid = pc->p_ruid;
824 oldgid = pc->p_rgid;
825
826
827 if (issuser) {
828 if (ISSET(strp->flags, STR_PROC_SETEUID))
829 strp->saveuid = systrace_seteuid(p, strp->seteuid);
830 if (ISSET(strp->flags, STR_PROC_SETEGID))
831 strp->savegid = systrace_setegid(p, strp->setegid);
832 } else
833 CLR(strp->flags, STR_PROC_SETEUID|STR_PROC_SETEGID);
834
835 rw_exit_write(&fst->lock);
836
837 error = (*callp->sy_call)(p, v, retval);
838
839
840 systrace_lock();
841 if ((strp = p->p_systrace) == NULL) {
842 systrace_unlock();
843 return (error);
844 }
845
846 if (issuser) {
847 if (ISSET(strp->flags, STR_PROC_SETEUID)) {
848 if (pc->pc_ucred->cr_uid == strp->seteuid)
849 systrace_seteuid(p, strp->saveuid);
850 CLR(strp->flags, STR_PROC_SETEUID);
851 }
852 if (ISSET(strp->flags, STR_PROC_SETEGID)) {
853 if (pc->pc_ucred->cr_gid == strp->setegid)
854 systrace_setegid(p, strp->savegid);
855 CLR(strp->flags, STR_PROC_SETEGID);
856 }
857 }
858
859 systrace_replacefree(strp);
860
861 if (ISSET(p->p_flag, P_SUGID) || ISSET(p->p_flag, P_SUGIDEXEC)) {
862 if ((fst = strp->parent) == NULL || !fst->issuser) {
863 systrace_unlock();
864 return (error);
865 }
866 }
867
868
869
870
871 if (ISSET(strp->flags, STR_PROC_REPORT)) {
872 CLR(strp->flags, STR_PROC_REPORT);
873 oldemul = NULL;
874 }
875
876
877 fst = strp->parent;
878 rw_enter_write(&fst->lock);
879 systrace_unlock();
880
881 if (p->p_emul != oldemul) {
882
883 if (strp->policy) {
884 systrace_closepolicy(fst, strp->policy);
885 strp->policy = NULL;
886 }
887 systrace_msg_emul(fst, strp);
888
889 REACQUIRE_LOCK;
890 }
891
892
893 if (olduid != p->p_cred->p_ruid ||
894 oldgid != p->p_cred->p_rgid) {
895 systrace_msg_ugid(fst, strp);
896
897 REACQUIRE_LOCK;
898 }
899
900
901 if (report) {
902 systrace_msg_result(fst, strp, error, code,
903 callp->sy_argsize, v, retval);
904
905
906 goto out;
907 }
908
909 out_unlock:
910 rw_exit_write(&fst->lock);
911 out:
912 return (error);
913 }
914
915 uid_t
916 systrace_seteuid(struct proc *p, uid_t euid)
917 {
918 struct pcred *pc = p->p_cred;
919 uid_t oeuid = pc->pc_ucred->cr_uid;
920
921 if (pc->pc_ucred->cr_uid == euid)
922 return (oeuid);
923
924
925
926
927 pc->pc_ucred = crcopy(pc->pc_ucred);
928 pc->pc_ucred->cr_uid = euid;
929 atomic_setbits_int(&p->p_flag, P_SUGID);
930
931 return (oeuid);
932 }
933
934 gid_t
935 systrace_setegid(struct proc *p, gid_t egid)
936 {
937 struct pcred *pc = p->p_cred;
938 gid_t oegid = pc->pc_ucred->cr_gid;
939
940 if (pc->pc_ucred->cr_gid == egid)
941 return (oegid);
942
943
944
945
946 pc->pc_ucred = crcopy(pc->pc_ucred);
947 pc->pc_ucred->cr_gid = egid;
948 atomic_setbits_int(&p->p_flag, P_SUGID);
949
950 return (oegid);
951 }
952
953
954
955 int
956 systrace_answer(struct str_process *strp, struct systrace_answer *ans)
957 {
958 int error = 0;
959
960 DPRINTF(("%s: %u: policy %d\n", __func__,
961 ans->stra_pid, ans->stra_policy));
962
963 if (!POLICY_VALID(ans->stra_policy)) {
964 error = EINVAL;
965 goto out;
966 }
967
968
969 if (ans->stra_seqnr != strp->seqnr) {
970 error = ESRCH;
971 goto out;
972 }
973
974 if ((error = systrace_processready(strp)) != 0)
975 goto out;
976
977 strp->answer = ans->stra_policy;
978 strp->error = ans->stra_error;
979 if (!strp->error)
980 strp->error = EPERM;
981 if (ISSET(ans->stra_flags, SYSTR_FLAGS_RESULT))
982 SET(strp->flags, STR_PROC_SYSCALLRES);
983
984
985 if (ISSET(ans->stra_flags, SYSTR_FLAGS_SETEUID)) {
986 SET(strp->flags, STR_PROC_SETEUID);
987 strp->seteuid = ans->stra_seteuid;
988 }
989 if (ISSET(ans->stra_flags, SYSTR_FLAGS_SETEGID)) {
990 SET(strp->flags, STR_PROC_SETEGID);
991 strp->setegid = ans->stra_setegid;
992 }
993
994
995 CLR(strp->flags, STR_PROC_WAITANSWER);
996 wakeup(strp);
997 out:
998
999 return (error);
1000 }
1001
1002 int
1003 systrace_setscriptname(struct str_process *strp, struct systrace_scriptname *ans)
1004 {
1005 strlcpy(strp->scriptname,
1006 ans->sn_scriptname, sizeof(strp->scriptname));
1007
1008 return (0);
1009 }
1010
1011 int
1012 systrace_inject(struct str_process *strp, int docopy)
1013 {
1014 int ind, ret = 0;
1015
1016 for (ind = 0; ind < strp->injectind; ind++) {
1017 struct str_inject *inject = &strp->injects[ind];
1018 if (!ret && docopy &&
1019 copyout(inject->kaddr, inject->uaddr, inject->len))
1020 ret = EINVAL;
1021 free(inject->kaddr, M_XDATA);
1022 }
1023
1024 strp->injectind = 0;
1025 return (ret);
1026 }
1027
1028 int
1029 systrace_prepinject(struct str_process *strp, struct systrace_inject *inj)
1030 {
1031 caddr_t udata, kaddr = NULL;
1032 int ret = 0;
1033 struct str_inject *inject;
1034
1035 if (strp->injectind >= SYSTR_MAXINJECTS)
1036 return (ENOBUFS);
1037
1038 udata = stackgap_alloc(&strp->sg, inj->stri_len);
1039 if (udata == NULL)
1040 return (ENOMEM);
1041
1042
1043
1044
1045
1046
1047 kaddr = malloc(inj->stri_len, M_XDATA, M_WAITOK);
1048 ret = copyin(inj->stri_addr, kaddr, inj->stri_len);
1049 if (ret) {
1050 free(kaddr, M_XDATA);
1051 return (ret);
1052 }
1053
1054 inject = &strp->injects[strp->injectind++];
1055 inject->kaddr = kaddr;
1056 inject->uaddr = inj->stri_addr = udata;
1057 inject->len = inj->stri_len;
1058
1059 return (0);
1060 }
1061
1062 int
1063 systrace_policy(struct fsystrace *fst, struct systrace_policy *pol)
1064 {
1065 struct str_policy *strpol;
1066 struct str_process *strp;
1067
1068 switch(pol->strp_op) {
1069 case SYSTR_POLICY_NEW:
1070 DPRINTF(("%s: new, ents %d\n", __func__,
1071 pol->strp_maxents));
1072 if (pol->strp_maxents <= 0 || pol->strp_maxents > 1024)
1073 return (EINVAL);
1074 strpol = systrace_newpolicy(fst, pol->strp_maxents);
1075 if (strpol == NULL)
1076 return (ENOBUFS);
1077 pol->strp_num = strpol->nr;
1078 break;
1079 case SYSTR_POLICY_ASSIGN:
1080 DPRINTF(("%s: %d -> pid %d\n", __func__,
1081 pol->strp_num, pol->strp_pid));
1082
1083
1084 TAILQ_FOREACH(strpol, &fst->policies, next)
1085 if (strpol->nr == pol->strp_num)
1086 break;
1087 if (strpol == NULL)
1088 return (EINVAL);
1089
1090 strp = systrace_findpid(fst, pol->strp_pid);
1091 if (strp == NULL)
1092 return (EINVAL);
1093
1094
1095 if (strpol->emul && strpol->emul != strp->proc->p_emul)
1096 return (EINVAL);
1097
1098 if (strp->policy)
1099 systrace_closepolicy(fst, strp->policy);
1100 strp->policy = strpol;
1101
1102
1103 TAILQ_REMOVE(&fst->policies, strpol, next);
1104 TAILQ_INSERT_TAIL(&fst->policies, strpol, next);
1105 strpol->refcount++;
1106
1107
1108 if (strpol->emul == NULL)
1109 strpol->emul = strp->proc->p_emul;
1110
1111 break;
1112 case SYSTR_POLICY_MODIFY:
1113 DPRINTF(("%s: %d: code %d -> policy %d\n", __func__,
1114 pol->strp_num, pol->strp_code, pol->strp_policy));
1115 if (!POLICY_VALID(pol->strp_policy))
1116 return (EINVAL);
1117 TAILQ_FOREACH(strpol, &fst->policies, next)
1118 if (strpol->nr == pol->strp_num)
1119 break;
1120 if (strpol == NULL)
1121 return (EINVAL);
1122 if (pol->strp_code < 0 || pol->strp_code >= strpol->nsysent)
1123 return (EINVAL);
1124 strpol->sysent[pol->strp_code] = pol->strp_policy;
1125 break;
1126 default:
1127 return (EINVAL);
1128 }
1129
1130 return (0);
1131 }
1132
1133 int
1134 systrace_processready(struct str_process *strp)
1135 {
1136 if (ISSET(strp->flags, STR_PROC_ONQUEUE))
1137 return (EBUSY);
1138
1139 if (!ISSET(strp->flags, STR_PROC_WAITANSWER))
1140 return (EBUSY);
1141
1142 if (strp->proc->p_stat != SSLEEP)
1143 return (EBUSY);
1144
1145 return (0);
1146 }
1147
1148 int
1149 systrace_getcwd(struct fsystrace *fst, struct str_process *strp)
1150 {
1151 struct filedesc *myfdp, *fdp;
1152 int error;
1153
1154 DPRINTF(("%s: %d\n", __func__, strp->pid));
1155
1156 error = systrace_processready(strp);
1157 if (error)
1158 return (error);
1159
1160 myfdp = curproc->p_fd;
1161 fdp = strp->proc->p_fd;
1162 if (myfdp == NULL || fdp == NULL)
1163 return (EINVAL);
1164
1165
1166 fst->fd_pid = strp->pid;
1167 fst->fd_cdir = myfdp->fd_cdir;
1168 fst->fd_rdir = myfdp->fd_rdir;
1169
1170 if ((myfdp->fd_cdir = fdp->fd_cdir) != NULL)
1171 VREF(myfdp->fd_cdir);
1172 if ((myfdp->fd_rdir = fdp->fd_rdir) != NULL)
1173 VREF(myfdp->fd_rdir);
1174
1175 return (0);
1176 }
1177
1178 int
1179 systrace_io(struct str_process *strp, struct systrace_io *io)
1180 {
1181 struct proc *p = curproc, *t = strp->proc;
1182 struct uio uio;
1183 struct iovec iov;
1184 int error = 0;
1185
1186 DPRINTF(("%s: %u: %p(%lu)\n", __func__,
1187 io->strio_pid, io->strio_offs, (u_long)io->strio_len));
1188
1189 switch (io->strio_op) {
1190 case SYSTR_READ:
1191 uio.uio_rw = UIO_READ;
1192 break;
1193 case SYSTR_WRITE:
1194 uio.uio_rw = UIO_WRITE;
1195 break;
1196 default:
1197 return (EINVAL);
1198 }
1199
1200 error = systrace_processready(strp);
1201 if (error)
1202 goto out;
1203
1204 iov.iov_base = io->strio_addr;
1205 iov.iov_len = io->strio_len;
1206 uio.uio_iov = &iov;
1207 uio.uio_iovcnt = 1;
1208 uio.uio_offset = (off_t)(u_long)io->strio_offs;
1209 uio.uio_resid = io->strio_len;
1210 uio.uio_segflg = UIO_USERSPACE;
1211 uio.uio_procp = p;
1212
1213 error = process_domem(p, t, &uio, PT_WRITE_I);
1214 io->strio_len -= uio.uio_resid;
1215 out:
1216
1217 return (error);
1218 }
1219
1220 int
1221 systrace_attach(struct fsystrace *fst, pid_t pid)
1222 {
1223 int error = 0;
1224 struct proc *proc, *p = curproc;
1225
1226 if ((proc = pfind(pid)) == NULL) {
1227 error = ESRCH;
1228 goto out;
1229 }
1230
1231 if (ISSET(proc->p_flag, P_INEXEC)) {
1232 error = EAGAIN;
1233 goto out;
1234 }
1235
1236
1237
1238
1239
1240 if (proc->p_pid == p->p_pid) {
1241 error = EINVAL;
1242 goto out;
1243 }
1244
1245
1246
1247
1248 if (ISSET(proc->p_flag, P_SYSTEM)) {
1249 error = EPERM;
1250 goto out;
1251 }
1252
1253
1254
1255
1256 if (ISSET(proc->p_flag, P_SYSTRACE)) {
1257 error = EBUSY;
1258 goto out;
1259 }
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 if ((proc->p_cred->p_ruid != p->p_cred->p_ruid ||
1273 ISSET(proc->p_flag, P_SUGID) ||
1274 ISSET(proc->p_flag, P_SUGIDEXEC)) &&
1275 (error = suser(p, 0)) != 0)
1276 goto out;
1277
1278
1279
1280
1281
1282
1283
1284 if ((proc->p_pid == 1) && (securelevel > -1)) {
1285 error = EPERM;
1286 goto out;
1287 }
1288
1289 error = systrace_insert_process(fst, proc);
1290
1291 out:
1292 return (error);
1293 }
1294
1295 void
1296 systrace_execve0(struct proc *p)
1297 {
1298 struct str_process *strp;
1299
1300 systrace_lock();
1301 strp = p->p_systrace;
1302 strp->isscript = 0;
1303 systrace_unlock();
1304 }
1305
1306 void
1307 systrace_execve1(char *path, struct proc *p)
1308 {
1309 struct str_process *strp;
1310 struct fsystrace *fst;
1311 struct str_msg_execve *msg_execve;
1312
1313 do {
1314 systrace_lock();
1315 strp = p->p_systrace;
1316 if (strp == NULL) {
1317 systrace_unlock();
1318 return;
1319 }
1320
1321 msg_execve = &strp->msg.msg_data.msg_execve;
1322 fst = strp->parent;
1323 rw_enter_write(&fst->lock);
1324 systrace_unlock();
1325
1326
1327
1328
1329
1330
1331 if (fst->issuser ||
1332 fst->p_ruid != p->p_cred->p_ruid ||
1333 fst->p_rgid != p->p_cred->p_rgid) {
1334 rw_exit_write(&fst->lock);
1335 return;
1336 }
1337 strlcpy(msg_execve->path, path, MAXPATHLEN);
1338 } while (systrace_make_msg(strp, SYSTR_MSG_EXECVE) != 0);
1339 }
1340
1341
1342
1343 int
1344 systrace_preprepl(struct str_process *strp, struct systrace_replace *repl)
1345 {
1346 size_t len;
1347 int i, ret = 0;
1348
1349 ret = systrace_processready(strp);
1350 if (ret)
1351 return (ret);
1352
1353 if (strp->replace != NULL) {
1354 free(strp->replace, M_XDATA);
1355 strp->replace = NULL;
1356 }
1357
1358 if (repl->strr_nrepl < 0 || repl->strr_nrepl > SYSTR_MAXARGS)
1359 return (EINVAL);
1360
1361 for (i = 0, len = 0; i < repl->strr_nrepl; i++) {
1362 if (repl->strr_argind[i] < 0 ||
1363 repl->strr_argind[i] >= SYSTR_MAXARGS)
1364 return (EINVAL);
1365 if (repl->strr_offlen[i] == 0)
1366 continue;
1367 len += repl->strr_offlen[i];
1368 if (repl->strr_offlen[i] > SYSTR_MAXREPLEN ||
1369 repl->strr_off[i] > SYSTR_MAXREPLEN ||
1370 len > SYSTR_MAXREPLEN)
1371 return (EINVAL);
1372 if (repl->strr_offlen[i] + repl->strr_off[i] > len)
1373 return (EINVAL);
1374 }
1375
1376
1377 if (repl->strr_len != len)
1378 return (EINVAL);
1379
1380
1381 if (repl->strr_len > SYSTR_MAXREPLEN)
1382 return (EINVAL);
1383
1384 strp->replace = (struct systrace_replace *)
1385 malloc(sizeof(struct systrace_replace) + len, M_XDATA, M_WAITOK);
1386
1387 memcpy(strp->replace, repl, sizeof(struct systrace_replace));
1388 ret = copyin(repl->strr_base, strp->replace + 1, len);
1389 if (ret) {
1390 free(strp->replace, M_XDATA);
1391 strp->replace = NULL;
1392 return (ret);
1393 }
1394
1395
1396 repl = strp->replace;
1397 repl->strr_base = (caddr_t)(repl + 1);
1398
1399 return (0);
1400 }
1401
1402
1403
1404
1405
1406 int
1407 systrace_replace(struct str_process *strp, size_t argsize, register_t args[])
1408 {
1409 struct systrace_replace *repl = strp->replace;
1410 caddr_t kdata, kbase;
1411 caddr_t udata, ubase;
1412 int i, maxarg, ind, ret = 0;
1413
1414 maxarg = argsize/sizeof(register_t);
1415 ubase = stackgap_alloc(&strp->sg, repl->strr_len);
1416 if (ubase == NULL) {
1417 ret = EINVAL;
1418 goto out;
1419 }
1420
1421 kbase = repl->strr_base;
1422 for (i = 0; i < maxarg && i < repl->strr_nrepl; i++) {
1423 ind = repl->strr_argind[i];
1424 if (ind < 0 || ind >= maxarg) {
1425 ret = EINVAL;
1426 goto out;
1427 }
1428 if (repl->strr_offlen[i] == 0) {
1429 args[ind] = repl->strr_off[i];
1430 continue;
1431 }
1432 kdata = kbase + repl->strr_off[i];
1433 if (repl->strr_flags[i] & SYSTR_NOLINKS) {
1434 ret = systrace_fname(strp, kdata, repl->strr_offlen[i]);
1435 if (ret != 0)
1436 goto out;
1437 }
1438 udata = ubase + repl->strr_off[i];
1439 if (copyout(kdata, udata, repl->strr_offlen[i])) {
1440 ret = EINVAL;
1441 goto out;
1442 }
1443
1444
1445 args[ind] = (register_t)udata;
1446 }
1447
1448 out:
1449 return (ret);
1450 }
1451
1452 int
1453 systrace_fname(struct str_process *strp, caddr_t kdata, size_t len)
1454 {
1455 if (strp->nfname >= SYSTR_MAXFNAME || len < 1)
1456 return EINVAL;
1457
1458 strp->fname[strp->nfname] = kdata;
1459 strp->fname[strp->nfname][len - 1] = '\0';
1460 strp->nfname++;
1461
1462 return 0;
1463 }
1464
1465 void
1466 systrace_replacefree(struct str_process *strp)
1467 {
1468 if (strp->replace != NULL) {
1469 free(strp->replace, M_XDATA);
1470 strp->replace = NULL;
1471 }
1472 while (strp->nfname > 0) {
1473 strp->nfname--;
1474 strp->fname[strp->nfname] = NULL;
1475 }
1476 }
1477 int
1478 systrace_scriptname(struct proc *p, char *dst)
1479 {
1480 struct str_process *strp;
1481 struct fsystrace *fst;
1482 int error = 0;
1483
1484 systrace_lock();
1485 strp = p->p_systrace;
1486 fst = strp->parent;
1487
1488 rw_enter_write(&fst->lock);
1489 systrace_unlock();
1490
1491 if (!fst->issuser && (ISSET(p->p_flag, P_SUGID) ||
1492 ISSET(p->p_flag, P_SUGIDEXEC) ||
1493 fst->p_ruid != p->p_cred->p_ruid ||
1494 fst->p_rgid != p->p_cred->p_rgid)) {
1495 error = EPERM;
1496 goto out;
1497 }
1498
1499 if (strp != NULL) {
1500 if (strp->scriptname[0] == '\0') {
1501 error = ENOENT;
1502 goto out;
1503 }
1504
1505 strlcpy(dst, strp->scriptname, MAXPATHLEN);
1506 strp->isscript = 1;
1507 }
1508
1509 out:
1510 strp->scriptname[0] = '\0';
1511 rw_exit_write(&fst->lock);
1512
1513 return (error);
1514 }
1515
1516 void
1517 systrace_namei(struct nameidata *ndp)
1518 {
1519 struct str_process *strp;
1520 struct fsystrace *fst;
1521 struct componentname *cnp = &ndp->ni_cnd;
1522 size_t i;
1523 int hamper = 0;
1524
1525 systrace_lock();
1526 strp = cnp->cn_proc->p_systrace;
1527 if (strp != NULL) {
1528 fst = strp->parent;
1529 rw_enter_write(&fst->lock);
1530 systrace_unlock();
1531
1532 for (i = 0; i < strp->nfname; i++)
1533 if (strcmp(cnp->cn_pnbuf, strp->fname[i]) == 0) {
1534 hamper = 1;
1535 break;
1536 }
1537
1538 if (!hamper && strp->isscript &&
1539 strcmp(cnp->cn_pnbuf, strp->scriptname) == 0)
1540 hamper = 1;
1541
1542 rw_exit_write(&fst->lock);
1543 } else
1544 systrace_unlock();
1545
1546 if (hamper) {
1547
1548 ndp->ni_loopcnt = MAXSYMLINKS;
1549 cnp->cn_flags &= ~FOLLOW;
1550 cnp->cn_flags |= NOFOLLOW;
1551 }
1552 }
1553
1554 struct str_process *
1555 systrace_findpid(struct fsystrace *fst, pid_t pid)
1556 {
1557 struct str_process *strp;
1558 struct proc *proc = NULL;
1559
1560 TAILQ_FOREACH(strp, &fst->processes, next)
1561 if (strp->pid == pid)
1562 break;
1563
1564 if (strp == NULL)
1565 return (NULL);
1566
1567 proc = systrace_find(strp);
1568
1569 return (proc ? strp : NULL);
1570 }
1571
1572 int
1573 systrace_detach(struct str_process *strp)
1574 {
1575 struct proc *proc;
1576 struct fsystrace *fst = NULL;
1577 int error = 0;
1578
1579 DPRINTF(("%s: Trying to detach from %d\n", __func__, strp->pid));
1580
1581 if ((proc = systrace_find(strp)) != NULL) {
1582 atomic_clearbits_int(&proc->p_flag, P_SYSTRACE);
1583 proc->p_systrace = NULL;
1584 } else
1585 error = ESRCH;
1586
1587 if (ISSET(strp->flags, STR_PROC_WAITANSWER)) {
1588 CLR(strp->flags, STR_PROC_WAITANSWER);
1589 wakeup(strp);
1590 }
1591
1592 fst = strp->parent;
1593 systrace_wakeup(fst);
1594
1595 if (ISSET(strp->flags, STR_PROC_ONQUEUE))
1596 TAILQ_REMOVE(&fst->messages, strp, msg_next);
1597
1598 TAILQ_REMOVE(&fst->processes, strp, next);
1599 fst->nprocesses--;
1600
1601 if (strp->policy)
1602 systrace_closepolicy(fst, strp->policy);
1603 systrace_replacefree(strp);
1604 pool_put(&systr_proc_pl, strp);
1605
1606 return (error);
1607 }
1608
1609 void
1610 systrace_closepolicy(struct fsystrace *fst, struct str_policy *policy)
1611 {
1612 if (--policy->refcount)
1613 return;
1614
1615 fst->npolicies--;
1616
1617 if (policy->nsysent)
1618 free(policy->sysent, M_XDATA);
1619
1620 TAILQ_REMOVE(&fst->policies, policy, next);
1621
1622 pool_put(&systr_policy_pl, policy);
1623 }
1624
1625
1626 int
1627 systrace_insert_process(struct fsystrace *fst, struct proc *proc)
1628 {
1629 struct str_process *strp;
1630
1631 strp = pool_get(&systr_proc_pl, PR_NOWAIT);
1632 if (strp == NULL)
1633 return (ENOBUFS);
1634
1635 memset((caddr_t)strp, 0, sizeof(struct str_process));
1636 strp->pid = proc->p_pid;
1637 strp->proc = proc;
1638 strp->parent = fst;
1639
1640 TAILQ_INSERT_TAIL(&fst->processes, strp, next);
1641 fst->nprocesses++;
1642
1643 proc->p_systrace = strp;
1644 atomic_setbits_int(&proc->p_flag, P_SYSTRACE);
1645
1646 return (0);
1647 }
1648
1649 struct str_policy *
1650 systrace_newpolicy(struct fsystrace *fst, int maxents)
1651 {
1652 struct str_policy *pol;
1653 int i;
1654
1655 if (fst->npolicies > SYSTR_MAX_POLICIES && !fst->issuser) {
1656 struct str_policy *tmp;
1657
1658
1659 TAILQ_FOREACH(tmp, &fst->policies, next) {
1660 if (tmp->refcount == 1)
1661 break;
1662 }
1663
1664 if (tmp == NULL)
1665 return (NULL);
1666
1667
1668 systrace_msg_policyfree(fst, tmp);
1669
1670 systrace_closepolicy(fst, tmp);
1671 }
1672
1673 pol = pool_get(&systr_policy_pl, PR_NOWAIT);
1674 if (pol == NULL)
1675 return (NULL);
1676
1677 DPRINTF(("%s: allocating %d -> %lu\n", __func__,
1678 maxents, (u_long)maxents * sizeof(int)));
1679
1680 memset((caddr_t)pol, 0, sizeof(struct str_policy));
1681
1682 pol->sysent = (u_char *)malloc(maxents * sizeof(u_char),
1683 M_XDATA, M_WAITOK);
1684 pol->nsysent = maxents;
1685 for (i = 0; i < maxents; i++)
1686 pol->sysent[i] = SYSTR_POLICY_ASK;
1687
1688 fst->npolicies++;
1689 pol->nr = fst->npolicynr++;
1690 pol->refcount = 1;
1691
1692 TAILQ_INSERT_TAIL(&fst->policies, pol, next);
1693
1694 return (pol);
1695 }
1696
1697 int
1698 systrace_msg_ask(struct fsystrace *fst, struct str_process *strp,
1699 int code, size_t argsize, register_t args[])
1700 {
1701 struct str_msg_ask *msg_ask = &strp->msg.msg_data.msg_ask;
1702 int i;
1703
1704 msg_ask->code = code;
1705 msg_ask->argsize = argsize;
1706 for (i = 0; i < (argsize/sizeof(register_t)) && i < SYSTR_MAXARGS; i++)
1707 msg_ask->args[i] = args[i];
1708
1709 return (systrace_make_msg(strp, SYSTR_MSG_ASK));
1710 }
1711
1712 int
1713 systrace_msg_result(struct fsystrace *fst, struct str_process *strp,
1714 int error, int code, size_t argsize, register_t args[], register_t rval[])
1715 {
1716 struct str_msg_ask *msg_ask = &strp->msg.msg_data.msg_ask;
1717 int i;
1718
1719 msg_ask->code = code;
1720 msg_ask->argsize = argsize;
1721 msg_ask->result = error;
1722 for (i = 0; i < (argsize/sizeof(register_t)) && i < SYSTR_MAXARGS; i++)
1723 msg_ask->args[i] = args[i];
1724
1725 msg_ask->rval[0] = rval[0];
1726 msg_ask->rval[1] = rval[1];
1727
1728 return (systrace_make_msg(strp, SYSTR_MSG_RES));
1729 }
1730
1731 int
1732 systrace_msg_emul(struct fsystrace *fst, struct str_process *strp)
1733 {
1734 struct str_msg_emul *msg_emul = &strp->msg.msg_data.msg_emul;
1735 struct proc *p = strp->proc;
1736
1737 memcpy(msg_emul->emul, p->p_emul->e_name, SYSTR_EMULEN);
1738
1739 return (systrace_make_msg(strp, SYSTR_MSG_EMUL));
1740 }
1741
1742 int
1743 systrace_msg_ugid(struct fsystrace *fst, struct str_process *strp)
1744 {
1745 struct str_msg_ugid *msg_ugid = &strp->msg.msg_data.msg_ugid;
1746 struct proc *p = strp->proc;
1747
1748 msg_ugid->uid = p->p_cred->p_ruid;
1749 msg_ugid->gid = p->p_cred->p_rgid;
1750
1751 return (systrace_make_msg(strp, SYSTR_MSG_UGID));
1752 }
1753
1754 int
1755 systrace_make_msg(struct str_process *strp, int type)
1756 {
1757 struct str_message *msg = &strp->msg;
1758 struct fsystrace *fst = strp->parent;
1759 int st, pri;
1760
1761 pri = PWAIT|PCATCH;
1762 if (type == SYSTR_MSG_EXECVE)
1763 pri &= ~PCATCH;
1764
1765 msg->msg_seqnr = ++strp->seqnr;
1766 msg->msg_type = type;
1767 msg->msg_pid = strp->pid;
1768 if (strp->policy)
1769 msg->msg_policy = strp->policy->nr;
1770 else
1771 msg->msg_policy = -1;
1772
1773 SET(strp->flags, STR_PROC_WAITANSWER);
1774 if (ISSET(strp->flags, STR_PROC_ONQUEUE))
1775 goto out;
1776
1777 TAILQ_INSERT_TAIL(&fst->messages, strp, msg_next);
1778 SET(strp->flags, STR_PROC_ONQUEUE);
1779
1780 out:
1781 systrace_wakeup(fst);
1782
1783
1784 rw_exit_write(&fst->lock);
1785
1786 while (1) {
1787 st = tsleep(strp, pri, "systrmsg", 0);
1788 if (st != 0)
1789 return (ERESTART);
1790
1791 if ((strp = curproc->p_systrace) == NULL)
1792 return (0);
1793 if (!ISSET(strp->flags, STR_PROC_WAITANSWER))
1794 break;
1795 }
1796
1797 return (0);
1798 }
1799
1800 int
1801 systrace_msg_child(struct fsystrace *fst, struct str_process *strp, pid_t npid)
1802 {
1803 struct str_process *nstrp;
1804 struct str_message *msg;
1805 struct str_msg_child *msg_child;
1806
1807 nstrp = pool_get(&systr_proc_pl, PR_WAITOK);
1808 memset(nstrp, 0, sizeof(struct str_process));
1809
1810 DPRINTF(("%s: %p: pid %d -> pid %d\n", __func__,
1811 nstrp, strp->pid, npid));
1812
1813 msg = &nstrp->msg;
1814 msg_child = &msg->msg_data.msg_child;
1815
1816 msg->msg_type = SYSTR_MSG_CHILD;
1817 msg->msg_pid = strp->pid;
1818 if (strp->policy)
1819 msg->msg_policy = strp->policy->nr;
1820 else
1821 msg->msg_policy = -1;
1822 msg_child->new_pid = npid;
1823
1824 TAILQ_INSERT_TAIL(&fst->messages, nstrp, msg_next);
1825
1826 systrace_wakeup(fst);
1827
1828 return (0);
1829 }
1830
1831 int
1832 systrace_msg_policyfree(struct fsystrace *fst, struct str_policy *strpol)
1833 {
1834 struct str_process *nstrp;
1835 struct str_message *msg;
1836
1837 nstrp = pool_get(&systr_proc_pl, PR_WAITOK);
1838 memset(nstrp, 0, sizeof(struct str_process));
1839
1840 DPRINTF(("%s: free %d\n", __func__, strpol->nr));
1841
1842 msg = &nstrp->msg;
1843
1844 msg->msg_type = SYSTR_MSG_POLICYFREE;
1845 msg->msg_policy = strpol->nr;
1846
1847 TAILQ_INSERT_TAIL(&fst->messages, nstrp, msg_next);
1848
1849 systrace_wakeup(fst);
1850
1851 return (0);
1852 }