xref: /freebsd/share/man/man4/filemon.4 (revision a8089ea5aee578e08acab2438e82fc9a9ae50ed8)
1.\" Copyright (c) 2012
2.\"	David E. O'Brien <obrien@FreeBSD.org>.  All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\"    must display the following acknowledgment:
14.\"	This product includes software developed by David E. O'Brien and
15.\"	contributors.
16.\" 4. Neither the name of the author nor the names of its contributors
17.\"    may be used to endorse or promote products derived from this software
18.\"    without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANT ABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.Dd August 1, 2023
33.Dt FILEMON 4
34.Os
35.Sh NAME
36.Nm filemon
37.Nd the filemon device
38.Sh SYNOPSIS
39.In dev/filemon/filemon.h
40.Sh DESCRIPTION
41The
42.Nm
43device allows a process to collect file operations data of its children.
44The device
45.Pa /dev/filemon
46responds to two
47.Xr ioctl 2
48calls.
49.Pp
50.Nm
51is not intended to be a security auditing tool.
52Many system calls are not tracked and binaries using a non-native ABI may not
53be fully audited.
54It is intended for auditing of processes for the purpose of determining their
55dependencies using an efficient and easily parsable format.
56An example of this is
57.Xr make 1
58which uses this module with
59.Sy .MAKE.MODE=meta
60to handle incremental builds more smartly.
61.Pp
62System calls are denoted using the following single letters:
63.Pp
64.Bl -tag -width indent -compact
65.It Ql A
66.Xr openat 2 .
67The next log entry may be lacking an absolute path or be inaccurate.
68.It Ql C
69.Xr chdir 2
70.It Ql D
71.Xr unlink 2
72.It Ql E
73.Xr exec 2
74.It Ql F
75.Xr fork 2 ,
76.Xr vfork 2
77.It Ql L
78.Xr link 2 ,
79.Xr linkat 2 ,
80.Xr symlink 2
81.It Ql M
82.Xr rename 2
83.It Ql R
84.Xr open 2
85or
86.Xr openat 2
87for read
88.It Ql W
89.Xr open 2
90or
91.Xr openat 2
92for write
93.It Ql X
94.Xr _exit 2
95.El
96.Pp
97Note that
98.Ql R
99following
100.Ql W
101records can represent a single
102.Xr open 2
103for R/W,
104or two separate
105.Xr open 2
106calls, one for
107.Ql R
108and one for
109.Ql W .
110Note that only successful system calls are captured.
111.Sh IOCTLS
112User mode programs communicate with the
113.Nm
114driver through a number of ioctls which are described below.
115Each takes a single argument.
116.Bl -tag -width ".Dv FILEMON_SET_PID"
117.It Dv FILEMON_SET_FD
118Write the internal tracing buffer to the supplied open file descriptor.
119.It Dv FILEMON_SET_PID
120Child process ID to trace.
121This should normally be done under the control of a parent in the child after
122.Xr fork 2
123but before anything else.
124See the example below.
125.El
126.Sh RETURN VALUES
127.\" .Rv -std ioctl
128The
129.Fn ioctl
130function returns the value 0 if successful;
131otherwise the value \-1 is returned and the global variable
132.Va errno
133is set to indicate the error.
134.Sh ERRORS
135The
136.Fn ioctl
137system call
138with
139.Dv FILEMON_SET_FD
140will fail if:
141.Bl -tag -width Er
142.It Bq Er EEXIST
143The
144.Nm
145handle is already associated with a file descriptor.
146.It Bq Er EINVAL
147The file descriptor has an invalid type and cannot be used for
148tracing.
149.It Bq Er EBADF
150The file descriptor is invalid or not opened for writing.
151.El
152.Pp
153The
154.Fn ioctl
155system call
156with
157.Dv FILEMON_SET_PID
158will fail if:
159.Bl -tag -width Er
160.It Bq Er ESRCH
161No process having the specified process ID exists.
162.It Bq Er EBUSY
163The process ID specified is already being traced and was not the current
164process.
165.El
166.Pp
167The
168.Fn close
169system call on the filemon file descriptor may fail with the errors from
170.Xr write 2
171if any error is encountered while writing the log.
172It may also fail if:
173.Bl -tag -width Er
174.It Bq Er EFAULT
175An invalid address was used for a traced system call argument, resulting in
176no log entry for the system call.
177.It Bq Er ENAMETOOLONG
178An argument for a traced system call was too long, resulting in
179no log entry for the system call.
180.El
181.Sh FILES
182.Bl -tag -width ".Pa /dev/filemon"
183.It Pa /dev/filemon
184.El
185.Sh EXAMPLES
186.Bd -literal
187#include <sys/types.h>
188#include <sys/stat.h>
189#include <sys/wait.h>
190#include <sys/ioctl.h>
191#include <dev/filemon/filemon.h>
192#include <fcntl.h>
193#include <err.h>
194#include <errno.h>
195#include <unistd.h>
196
197static void
198open_filemon(void)
199{
200	pid_t child, wait_rv;
201	int fm_fd, fm_log;
202
203	if ((fm_fd = open("/dev/filemon", O_RDWR | O_CLOEXEC)) == -1)
204		err(1, "open(\e"/dev/filemon\e", O_RDWR)");
205	if ((fm_log = open("filemon.out",
206	    O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, DEFFILEMODE)) == -1)
207		err(1, "open(filemon.out)");
208
209	if (ioctl(fm_fd, FILEMON_SET_FD, &fm_log) == -1)
210		err(1, "Cannot set filemon log file descriptor");
211
212	if ((child = fork()) == 0) {
213		child = getpid();
214		if (ioctl(fm_fd, FILEMON_SET_PID, &child) == -1)
215			err(1, "Cannot set filemon PID");
216		/* Do something here. */
217	} else if (child == -1)
218		err(1, "Cannot fork child");
219	else {
220		while ((wait_rv = wait(&child)) == -1 &&
221		    errno == EINTR)
222			;
223		if (wait_rv == -1)
224			err(1, "cannot wait for child");
225		close(fm_fd);
226	}
227}
228.Ed
229.Pp
230Creates a file named
231.Pa filemon.out
232and configures the
233.Nm
234device to write the
235.Nm
236buffer contents to it.
237.Sh SEE ALSO
238.Xr dtrace 1 ,
239.Xr ktrace 1 ,
240.Xr script 1 ,
241.Xr truss 1 ,
242.Xr ioctl 2
243.Sh HISTORY
244A
245.Nm
246device appeared in
247.Fx 9.1 .
248.Sh BUGS
249Unloading the module may panic the system, thus requires using
250.Ic kldunload -f .
251