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