xref: /freebsd/sys/dev/filemon/filemon_wrapper.c (revision 9a41df2a0e6408e9b329bbd8b9e37c2b44461a1b)
1 /*-
2  * Copyright (c) 2011, David E. O'Brien.
3  * Copyright (c) 2009-2011, Juniper Networks, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY JUNIPER NETWORKS AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL JUNIPER NETWORKS OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #if __FreeBSD_version > 800032
32 #define FILEMON_HAS_LINKAT
33 #endif
34 
35 #if __FreeBSD_version < 900044	/* r225617 (2011-09-16) failed to bump
36 				   __FreeBSD_version.  This really should
37 				   be based on "900045".  "900044" is r225469
38 				   (2011-09-10) so this code is broken for
39 				   9-CURRENT September 10th-16th. */
40 #define sys_chdir	chdir
41 #define sys_execve	execve
42 #define sys_fork	fork
43 #define sys_link	link
44 #define sys_open	open
45 #define sys_rename	rename
46 #define sys_stat	stat
47 #define sys_symlink	symlink
48 #define sys_unlink	unlink
49 #define sys_vfork	vfork
50 #define sys_sys_exit	sys_exit
51 #ifdef FILEMON_HAS_LINKAT
52 #define sys_linkat	linkat
53 #endif
54 #endif	/* __FreeBSD_version */
55 
56 static void
57 filemon_output(struct filemon *filemon, char *msg, size_t len)
58 {
59 	struct uio auio;
60 	struct iovec aiov;
61 
62 	if (filemon->fp == NULL)
63 		return;
64 
65 	aiov.iov_base = msg;
66 	aiov.iov_len = len;
67 	auio.uio_iov = &aiov;
68 	auio.uio_iovcnt = 1;
69 	auio.uio_resid = len;
70 	auio.uio_segflg = UIO_SYSSPACE;
71 	auio.uio_rw = UIO_WRITE;
72 	auio.uio_td = curthread;
73 	auio.uio_offset = (off_t) -1;
74 
75 	bwillwrite();
76 
77 	fo_write(filemon->fp, &auio, curthread->td_ucred, 0, curthread);
78 }
79 
80 static struct filemon *
81 filemon_pid_check(struct proc *p)
82 {
83 	struct filemon *filemon;
84 
85 	TAILQ_FOREACH(filemon, &filemons_inuse, link) {
86 		if (p->p_pid == filemon->pid)
87 			return (filemon);
88 	}
89 
90 	if (p->p_pptr == NULL)
91 		return (NULL);
92 
93 	return (filemon_pid_check(p->p_pptr));
94 }
95 
96 static void
97 filemon_comment(struct filemon *filemon)
98 {
99 	int len;
100 	struct timeval now;
101 
102 	/* Load timestamp before locking.  Less accurate but less contention. */
103 	getmicrotime(&now);
104 
105 	/* Grab a read lock on the filemon inuse list. */
106 	filemon_lock_read();
107 
108 	/* Lock the found filemon structure. */
109 	filemon_filemon_lock(filemon);
110 
111 	len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr),
112 	    "# filemon version %d\n# Target pid %d\n# Start %ju.%06ju\nV %d\n",
113 	    FILEMON_VERSION, curproc->p_pid, (uintmax_t)now.tv_sec,
114 	    (uintmax_t)now.tv_usec, FILEMON_VERSION);
115 
116 	filemon_output(filemon, filemon->msgbufr, len);
117 
118 	/* Unlock the found filemon structure. */
119 	filemon_filemon_unlock(filemon);
120 
121 	/* Release the read lock. */
122 	filemon_unlock_read();
123 }
124 
125 static int
126 filemon_wrapper_chdir(struct thread *td, struct chdir_args *uap)
127 {
128 	int ret;
129 	size_t done;
130 	size_t len;
131 	struct filemon *filemon;
132 
133 	if ((ret = sys_chdir(td, uap)) == 0) {
134 		/* Grab a read lock on the filemon inuse list. */
135 		filemon_lock_read();
136 
137 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
138 			/* Lock the found filemon structure. */
139 			filemon_filemon_lock(filemon);
140 
141 			copyinstr(uap->path, filemon->fname1,
142 			    sizeof(filemon->fname1), &done);
143 
144 			len = snprintf(filemon->msgbufr,
145 			    sizeof(filemon->msgbufr), "C %d %s\n",
146 			    curproc->p_pid, filemon->fname1);
147 
148 			filemon_output(filemon, filemon->msgbufr, len);
149 
150 			/* Unlock the found filemon structure. */
151 			filemon_filemon_unlock(filemon);
152 		}
153 
154 		/* Release the read lock. */
155 		filemon_unlock_read();
156 	}
157 
158 	return (ret);
159 }
160 
161 static int
162 filemon_wrapper_execve(struct thread *td, struct execve_args *uap)
163 {
164 	char fname[MAXPATHLEN];
165 	int ret;
166 	size_t done;
167 	size_t len;
168 	struct filemon *filemon;
169 
170 	copyinstr(uap->fname, fname, sizeof(fname), &done);
171 
172 	if ((ret = sys_execve(td, uap)) == 0) {
173 		/* Grab a read lock on the filemon inuse list. */
174 		filemon_lock_read();
175 
176 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
177 			/* Lock the found filemon structure. */
178 			filemon_filemon_lock(filemon);
179 
180 			len = snprintf(filemon->msgbufr,
181 			    sizeof(filemon->msgbufr), "E %d %s\n",
182 			    curproc->p_pid, fname);
183 
184 			filemon_output(filemon, filemon->msgbufr, len);
185 
186 			/* Unlock the found filemon structure. */
187 			filemon_filemon_unlock(filemon);
188 		}
189 
190 		/* Release the read lock. */
191 		filemon_unlock_read();
192 	}
193 
194 	return (ret);
195 }
196 
197 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
198 static int
199 filemon_wrapper_freebsd32_execve(struct thread *td,
200     struct freebsd32_execve_args *uap)
201 {
202 	char fname[MAXPATHLEN];
203 	int ret;
204 	size_t done;
205 	size_t len;
206 	struct filemon *filemon;
207 
208 	copyinstr(uap->fname, fname, sizeof(fname), &done);
209 
210 	if ((ret = freebsd32_execve(td, uap)) == 0) {
211 		/* Grab a read lock on the filemon inuse list. */
212 		filemon_lock_read();
213 
214 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
215 			/* Lock the found filemon structure. */
216 			filemon_filemon_lock(filemon);
217 
218 			len = snprintf(filemon->msgbufr,
219 			    sizeof(filemon->msgbufr), "E %d %s\n",
220 			    curproc->p_pid, fname);
221 
222 			filemon_output(filemon, filemon->msgbufr, len);
223 
224 			/* Unlock the found filemon structure. */
225 			filemon_filemon_unlock(filemon);
226 		}
227 
228 		/* Release the read lock. */
229 		filemon_unlock_read();
230 	}
231 
232 	return (ret);
233 }
234 #endif
235 
236 static int
237 filemon_wrapper_fork(struct thread *td, struct fork_args *uap)
238 {
239 	int ret;
240 	size_t len;
241 	struct filemon *filemon;
242 
243 	if ((ret = sys_fork(td, uap)) == 0) {
244 		/* Grab a read lock on the filemon inuse list. */
245 		filemon_lock_read();
246 
247 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
248 			/* Lock the found filemon structure. */
249 			filemon_filemon_lock(filemon);
250 
251 			len = snprintf(filemon->msgbufr,
252 			    sizeof(filemon->msgbufr), "F %d %ld\n",
253 			    curproc->p_pid, (long)curthread->td_retval[0]);
254 
255 			filemon_output(filemon, filemon->msgbufr, len);
256 
257 			/* Unlock the found filemon structure. */
258 			filemon_filemon_unlock(filemon);
259 		}
260 
261 		/* Release the read lock. */
262 		filemon_unlock_read();
263 	}
264 
265 	return (ret);
266 }
267 
268 static int
269 filemon_wrapper_open(struct thread *td, struct open_args *uap)
270 {
271 	int ret;
272 	size_t done;
273 	size_t len;
274 	struct filemon *filemon;
275 
276 	if ((ret = sys_open(td, uap)) == 0) {
277 		/* Grab a read lock on the filemon inuse list. */
278 		filemon_lock_read();
279 
280 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
281 			/* Lock the found filemon structure. */
282 			filemon_filemon_lock(filemon);
283 
284 			copyinstr(uap->path, filemon->fname1,
285 			    sizeof(filemon->fname1), &done);
286 
287 			if (uap->flags & O_RDWR) {
288 				/*
289 				 * We'll get the W record below, but need
290 				 * to also output an R to distingish from
291 				 * O_WRONLY.
292 				 */
293 				len = snprintf(filemon->msgbufr,
294 				    sizeof(filemon->msgbufr), "R %d %s\n",
295 				    curproc->p_pid, filemon->fname1);
296 				filemon_output(filemon, filemon->msgbufr, len);
297 			}
298 
299 
300 			len = snprintf(filemon->msgbufr,
301 			    sizeof(filemon->msgbufr), "%c %d %s\n",
302 			    (uap->flags & O_ACCMODE) ? 'W':'R',
303 			    curproc->p_pid, filemon->fname1);
304 			filemon_output(filemon, filemon->msgbufr, len);
305 
306 			/* Unlock the found filemon structure. */
307 			filemon_filemon_unlock(filemon);
308 		}
309 
310 		/* Release the read lock. */
311 		filemon_unlock_read();
312 	}
313 
314 	return (ret);
315 }
316 
317 static int
318 filemon_wrapper_rename(struct thread *td, struct rename_args *uap)
319 {
320 	int ret;
321 	size_t done;
322 	size_t len;
323 	struct filemon *filemon;
324 
325 	if ((ret = sys_rename(td, uap)) == 0) {
326 		/* Grab a read lock on the filemon inuse list. */
327 		filemon_lock_read();
328 
329 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
330 			/* Lock the found filemon structure. */
331 			filemon_filemon_lock(filemon);
332 
333 			copyinstr(uap->from, filemon->fname1,
334 			    sizeof(filemon->fname1), &done);
335 			copyinstr(uap->to, filemon->fname2,
336 			    sizeof(filemon->fname2), &done);
337 
338 			len = snprintf(filemon->msgbufr,
339 			    sizeof(filemon->msgbufr), "M %d '%s' '%s'\n",
340 			    curproc->p_pid, filemon->fname1, filemon->fname2);
341 
342 			filemon_output(filemon, filemon->msgbufr, len);
343 
344 			/* Unlock the found filemon structure. */
345 			filemon_filemon_unlock(filemon);
346 		}
347 
348 		/* Release the read lock. */
349 		filemon_unlock_read();
350 	}
351 
352 	return (ret);
353 }
354 
355 static int
356 filemon_wrapper_link(struct thread *td, struct link_args *uap)
357 {
358 	int ret;
359 	size_t done;
360 	size_t len;
361 	struct filemon *filemon;
362 
363 	if ((ret = sys_link(td, uap)) == 0) {
364 		/* Grab a read lock on the filemon inuse list. */
365 		filemon_lock_read();
366 
367 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
368 			/* Lock the found filemon structure. */
369 			filemon_filemon_lock(filemon);
370 
371 			copyinstr(uap->path, filemon->fname1,
372 			    sizeof(filemon->fname1), &done);
373 			copyinstr(uap->link, filemon->fname2,
374 			    sizeof(filemon->fname2), &done);
375 
376 			len = snprintf(filemon->msgbufr,
377 			    sizeof(filemon->msgbufr), "L %d '%s' '%s'\n",
378 			    curproc->p_pid, filemon->fname1, filemon->fname2);
379 
380 			filemon_output(filemon, filemon->msgbufr, len);
381 
382 			/* Unlock the found filemon structure. */
383 			filemon_filemon_unlock(filemon);
384 		}
385 
386 		/* Release the read lock. */
387 		filemon_unlock_read();
388 	}
389 
390 	return (ret);
391 }
392 
393 static int
394 filemon_wrapper_symlink(struct thread *td, struct symlink_args *uap)
395 {
396 	int ret;
397 	size_t done;
398 	size_t len;
399 	struct filemon *filemon;
400 
401 	if ((ret = sys_symlink(td, uap)) == 0) {
402 		/* Grab a read lock on the filemon inuse list. */
403 		filemon_lock_read();
404 
405 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
406 			/* Lock the found filemon structure. */
407 			filemon_filemon_lock(filemon);
408 
409 			copyinstr(uap->path, filemon->fname1,
410 			    sizeof(filemon->fname1), &done);
411 			copyinstr(uap->link, filemon->fname2,
412 			    sizeof(filemon->fname2), &done);
413 
414 			len = snprintf(filemon->msgbufr,
415 			    sizeof(filemon->msgbufr), "L %d '%s' '%s'\n",
416 			    curproc->p_pid, filemon->fname1, filemon->fname2);
417 
418 			filemon_output(filemon, filemon->msgbufr, len);
419 
420 			/* Unlock the found filemon structure. */
421 			filemon_filemon_unlock(filemon);
422 		}
423 
424 		/* Release the read lock. */
425 		filemon_unlock_read();
426 	}
427 
428 	return (ret);
429 }
430 
431 #ifdef FILEMON_HAS_LINKAT
432 static int
433 filemon_wrapper_linkat(struct thread *td, struct linkat_args *uap)
434 {
435 	int ret;
436 	size_t done;
437 	size_t len;
438 	struct filemon *filemon;
439 
440 	if ((ret = sys_linkat(td, uap)) == 0) {
441 		/* Grab a read lock on the filemon inuse list. */
442 		filemon_lock_read();
443 
444 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
445 			/* Lock the found filemon structure. */
446 			filemon_filemon_lock(filemon);
447 
448 			copyinstr(uap->path1, filemon->fname1,
449 			    sizeof(filemon->fname1), &done);
450 			copyinstr(uap->path2, filemon->fname2,
451 			    sizeof(filemon->fname2), &done);
452 
453 			len = snprintf(filemon->msgbufr,
454 			    sizeof(filemon->msgbufr), "L %d '%s' '%s'\n",
455 			    curproc->p_pid, filemon->fname1, filemon->fname2);
456 
457 			filemon_output(filemon, filemon->msgbufr, len);
458 
459 			/* Unlock the found filemon structure. */
460 			filemon_filemon_unlock(filemon);
461 		}
462 
463 		/* Release the read lock. */
464 		filemon_unlock_read();
465 	}
466 
467 	return (ret);
468 }
469 #endif
470 
471 static int
472 filemon_wrapper_stat(struct thread *td, struct stat_args *uap)
473 {
474 	int ret;
475 	size_t done;
476 	size_t len;
477 	struct filemon *filemon;
478 
479 	if ((ret = sys_stat(td, uap)) == 0) {
480 		/* Grab a read lock on the filemon inuse list. */
481 		filemon_lock_read();
482 
483 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
484 			/* Lock the found filemon structure. */
485 			filemon_filemon_lock(filemon);
486 
487 			copyinstr(uap->path, filemon->fname1,
488 			    sizeof(filemon->fname1), &done);
489 
490 			len = snprintf(filemon->msgbufr,
491 			    sizeof(filemon->msgbufr), "S %d %s\n",
492 			    curproc->p_pid, filemon->fname1);
493 
494 			filemon_output(filemon, filemon->msgbufr, len);
495 
496 			/* Unlock the found filemon structure. */
497 			filemon_filemon_unlock(filemon);
498 		}
499 
500 		/* Release the read lock. */
501 		filemon_unlock_read();
502 	}
503 
504 	return (ret);
505 }
506 
507 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
508 static int
509 filemon_wrapper_freebsd32_stat(struct thread *td,
510     struct freebsd32_stat_args *uap)
511 {
512 	int ret;
513 	size_t done;
514 	size_t len;
515 	struct filemon *filemon;
516 
517 	if ((ret = freebsd32_stat(td, uap)) == 0) {
518 		/* Grab a read lock on the filemon inuse list. */
519 		filemon_lock_read();
520 
521 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
522 			/* Lock the found filemon structure. */
523 			filemon_filemon_lock(filemon);
524 
525 			copyinstr(uap->path, filemon->fname1,
526 			    sizeof(filemon->fname1), &done);
527 
528 			len = snprintf(filemon->msgbufr,
529 			    sizeof(filemon->msgbufr), "S %d %s\n",
530 			    curproc->p_pid, filemon->fname1);
531 
532 			filemon_output(filemon, filemon->msgbufr, len);
533 
534 			/* Unlock the found filemon structure. */
535 			filemon_filemon_unlock(filemon);
536 		}
537 
538 		/* Release the read lock. */
539 		filemon_unlock_read();
540 	}
541 
542 	return (ret);
543 }
544 #endif
545 
546 static void
547 filemon_wrapper_sys_exit(struct thread *td, struct sys_exit_args *uap)
548 {
549 	size_t len;
550 	struct filemon *filemon;
551 	struct timeval now;
552 
553 	/* Get timestamp before locking. */
554 	getmicrotime(&now);
555 
556 	/* Grab a read lock on the filemon inuse list. */
557 	filemon_lock_read();
558 
559 	if ((filemon = filemon_pid_check(curproc)) != NULL) {
560 		/* Lock the found filemon structure. */
561 		filemon_filemon_lock(filemon);
562 
563 		len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr),
564 		    "X %d %d\n", curproc->p_pid, uap->rval);
565 
566 		filemon_output(filemon, filemon->msgbufr, len);
567 
568 		/* Check if the monitored process is about to exit. */
569 		if (filemon->pid == curproc->p_pid) {
570 			len = snprintf(filemon->msgbufr,
571 			    sizeof(filemon->msgbufr),
572 			    "# Stop %ju.%06ju\n# Bye bye\n",
573 			    (uintmax_t)now.tv_sec, (uintmax_t)now.tv_usec);
574 
575 			filemon_output(filemon, filemon->msgbufr, len);
576 		}
577 
578 		/* Unlock the found filemon structure. */
579 		filemon_filemon_unlock(filemon);
580 	}
581 
582 	/* Release the read lock. */
583 	filemon_unlock_read();
584 
585 	sys_sys_exit(td, uap);
586 }
587 
588 static int
589 filemon_wrapper_unlink(struct thread *td, struct unlink_args *uap)
590 {
591 	int ret;
592 	size_t done;
593 	size_t len;
594 	struct filemon *filemon;
595 
596 	if ((ret = sys_unlink(td, uap)) == 0) {
597 		/* Grab a read lock on the filemon inuse list. */
598 		filemon_lock_read();
599 
600 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
601 			/* Lock the found filemon structure. */
602 			filemon_filemon_lock(filemon);
603 
604 			copyinstr(uap->path, filemon->fname1,
605 			    sizeof(filemon->fname1), &done);
606 
607 			len = snprintf(filemon->msgbufr,
608 			    sizeof(filemon->msgbufr), "D %d %s\n",
609 			    curproc->p_pid, filemon->fname1);
610 
611 			filemon_output(filemon, filemon->msgbufr, len);
612 
613 			/* Unlock the found filemon structure. */
614 			filemon_filemon_unlock(filemon);
615 		}
616 
617 		/* Release the read lock. */
618 		filemon_unlock_read();
619 	}
620 
621 	return (ret);
622 }
623 
624 static int
625 filemon_wrapper_vfork(struct thread *td, struct vfork_args *uap)
626 {
627 	int ret;
628 	size_t len;
629 	struct filemon *filemon;
630 
631 	if ((ret = sys_vfork(td, uap)) == 0) {
632 		/* Grab a read lock on the filemon inuse list. */
633 		filemon_lock_read();
634 
635 		if ((filemon = filemon_pid_check(curproc)) != NULL) {
636 			/* Lock the found filemon structure. */
637 			filemon_filemon_lock(filemon);
638 
639 			len = snprintf(filemon->msgbufr,
640 			    sizeof(filemon->msgbufr), "F %d %ld\n",
641 			    curproc->p_pid, (long)curthread->td_retval[0]);
642 
643 			filemon_output(filemon, filemon->msgbufr, len);
644 
645 			/* Unlock the found filemon structure. */
646 			filemon_filemon_unlock(filemon);
647 		}
648 
649 		/* Release the read lock. */
650 		filemon_unlock_read();
651 	}
652 
653 	return (ret);
654 }
655 
656 static void
657 filemon_wrapper_install(void)
658 {
659 #if defined(__LP64__)
660 	struct sysent *sv_table = elf64_freebsd_sysvec.sv_table;
661 #else
662 	struct sysent *sv_table = elf32_freebsd_sysvec.sv_table;
663 #endif
664 
665 	sv_table[SYS_chdir].sy_call = (sy_call_t *) filemon_wrapper_chdir;
666 	sv_table[SYS_exit].sy_call = (sy_call_t *) filemon_wrapper_sys_exit;
667 	sv_table[SYS_execve].sy_call = (sy_call_t *) filemon_wrapper_execve;
668 	sv_table[SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork;
669 	sv_table[SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open;
670 	sv_table[SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename;
671 	sv_table[SYS_stat].sy_call = (sy_call_t *) filemon_wrapper_stat;
672 	sv_table[SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink;
673 	sv_table[SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork;
674 	sv_table[SYS_link].sy_call = (sy_call_t *) filemon_wrapper_link;
675 	sv_table[SYS_symlink].sy_call = (sy_call_t *) filemon_wrapper_symlink;
676 #ifdef FILEMON_HAS_LINKAT
677 	sv_table[SYS_linkat].sy_call = (sy_call_t *) filemon_wrapper_linkat;
678 #endif
679 
680 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
681 	sv_table = ia32_freebsd_sysvec.sv_table;
682 
683 	sv_table[FREEBSD32_SYS_chdir].sy_call = (sy_call_t *) filemon_wrapper_chdir;
684 	sv_table[FREEBSD32_SYS_exit].sy_call = (sy_call_t *) filemon_wrapper_sys_exit;
685 	sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_execve;
686 	sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork;
687 	sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open;
688 	sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename;
689 	sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_stat;
690 	sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink;
691 	sv_table[FREEBSD32_SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork;
692 	sv_table[FREEBSD32_SYS_link].sy_call = (sy_call_t *) filemon_wrapper_link;
693 	sv_table[FREEBSD32_SYS_symlink].sy_call = (sy_call_t *) filemon_wrapper_symlink;
694 #ifdef FILEMON_HAS_LINKAT
695 	sv_table[FREEBSD32_SYS_linkat].sy_call = (sy_call_t *) filemon_wrapper_linkat;
696 #endif
697 #endif	/* COMPAT_ARCH32 */
698 }
699 
700 static void
701 filemon_wrapper_deinstall(void)
702 {
703 #if defined(__LP64__)
704 	struct sysent *sv_table = elf64_freebsd_sysvec.sv_table;
705 #else
706 	struct sysent *sv_table = elf32_freebsd_sysvec.sv_table;
707 #endif
708 
709 	sv_table[SYS_chdir].sy_call = (sy_call_t *)sys_chdir;
710 	sv_table[SYS_exit].sy_call = (sy_call_t *)sys_sys_exit;
711 	sv_table[SYS_execve].sy_call = (sy_call_t *)sys_execve;
712 	sv_table[SYS_fork].sy_call = (sy_call_t *)sys_fork;
713 	sv_table[SYS_open].sy_call = (sy_call_t *)sys_open;
714 	sv_table[SYS_rename].sy_call = (sy_call_t *)sys_rename;
715 	sv_table[SYS_stat].sy_call = (sy_call_t *)sys_stat;
716 	sv_table[SYS_unlink].sy_call = (sy_call_t *)sys_unlink;
717 	sv_table[SYS_vfork].sy_call = (sy_call_t *)sys_vfork;
718 	sv_table[SYS_link].sy_call = (sy_call_t *)sys_link;
719 	sv_table[SYS_symlink].sy_call = (sy_call_t *)sys_symlink;
720 #ifdef FILEMON_HAS_LINKAT
721 	sv_table[SYS_linkat].sy_call = (sy_call_t *)sys_linkat;
722 #endif
723 
724 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
725 	sv_table = ia32_freebsd_sysvec.sv_table;
726 
727 	sv_table[FREEBSD32_SYS_chdir].sy_call = (sy_call_t *)sys_chdir;
728 	sv_table[FREEBSD32_SYS_exit].sy_call = (sy_call_t *)sys_sys_exit;
729 	sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *)freebsd32_execve;
730 	sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *)sys_fork;
731 	sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *)sys_open;
732 	sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *)sys_rename;
733 	sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *)freebsd32_stat;
734 	sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *)sys_unlink;
735 	sv_table[FREEBSD32_SYS_vfork].sy_call = (sy_call_t *)sys_vfork;
736 	sv_table[FREEBSD32_SYS_link].sy_call = (sy_call_t *)sys_link;
737 	sv_table[FREEBSD32_SYS_symlink].sy_call = (sy_call_t *)sys_symlink;
738 #ifdef FILEMON_HAS_LINKAT
739 	sv_table[FREEBSD32_SYS_linkat].sy_call = (sy_call_t *)sys_linkat;
740 #endif
741 #endif	/* COMPAT_ARCH32 */
742 }
743