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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
<table class="head">
<tr>
<td class="head-ltitle">FILEMON(4)</td>
<td class="head-vol">Device Drivers Manual</td>
<td class="head-rtitle">FILEMON(4)</td>
</tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">filemon</code> — <span class="Nd">the
filemon device</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="Cd">device filemon</code></p>
<p class="Pp">
<br/>
<code class="In">#include
<<a class="In">dev/filemon/filemon.h</a>></code></p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">filemon</code> device allows a process to
collect file operations data of its children. The device
<span class="Pa">/dev/filemon</span> responds to two
<a class="Xr">ioctl(2)</a> calls.</p>
<p class="Pp" id=".MAKE.MODE=meta"><code class="Nm">filemon</code> is not
intended to be a security auditing tool. Many system calls are not tracked
and binaries using a non-native ABI may not be fully audited. It is intended
for auditing of processes for the purpose of determining their dependencies
using an efficient and easily parsable format. An example of this is
<a class="Xr">make(1)</a> which uses this module with
<a class="permalink" href="#.MAKE.MODE=meta"><b class="Sy">.MAKE.MODE=meta</b></a>
to handle incremental builds more smartly.</p>
<p class="Pp">System calls are denoted using the following single letters:</p>
<p class="Pp"></p>
<dl class="Bl-tag Bl-compact">
<dt>‘<code class="Li">A</code>’</dt>
<dd><a class="Xr">openat(2)</a>. The next log entry may be lacking an absolute
path or be inaccurate.</dd>
<dt>‘<code class="Li">C</code>’</dt>
<dd><a class="Xr">chdir(2)</a></dd>
<dt>‘<code class="Li">D</code>’</dt>
<dd><a class="Xr">unlink(2)</a></dd>
<dt>‘<code class="Li">E</code>’</dt>
<dd><a class="Xr">execve(2)</a></dd>
<dt>‘<code class="Li">F</code>’</dt>
<dd><a class="Xr">fork(2)</a>, <a class="Xr">vfork(2)</a></dd>
<dt>‘<code class="Li">L</code>’</dt>
<dd><a class="Xr">link(2)</a>, <a class="Xr">linkat(2)</a>,
<a class="Xr">symlink(2)</a></dd>
<dt>‘<code class="Li">M</code>’</dt>
<dd><a class="Xr">rename(2)</a></dd>
<dt>‘<code class="Li">R</code>’</dt>
<dd><a class="Xr">open(2)</a> or <a class="Xr">openat(2)</a> for read</dd>
<dt>‘<code class="Li">W</code>’</dt>
<dd><a class="Xr">open(2)</a> or <a class="Xr">openat(2)</a> for write</dd>
<dt>‘<code class="Li">X</code>’</dt>
<dd><a class="Xr">_exit(2)</a></dd>
</dl>
<p class="Pp">Note that ‘<code class="Li">R</code>’ following
‘<code class="Li">W</code>’ records can represent a single
<a class="Xr">open(2)</a> for R/W, or two separate <a class="Xr">open(2)</a>
calls, one for ‘<code class="Li">R</code>’ and one for
‘<code class="Li">W</code>’. Note that only successful system
calls are captured.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="IOCTLS"><a class="permalink" href="#IOCTLS">IOCTLS</a></h1>
<p class="Pp">User mode programs communicate with the
<code class="Nm">filemon</code> driver through a number of ioctls which are
described below. Each takes a single argument.</p>
<dl class="Bl-tag">
<dt id="FILEMON_SET_FD"><a class="permalink" href="#FILEMON_SET_FD"><code class="Dv">FILEMON_SET_FD</code></a></dt>
<dd>Write the internal tracing buffer to the supplied open file
descriptor.</dd>
<dt id="FILEMON_SET_PID"><a class="permalink" href="#FILEMON_SET_PID"><code class="Dv">FILEMON_SET_PID</code></a></dt>
<dd>Child process ID to trace. This should normally be done under the control
of a parent in the child after <a class="Xr">fork(2)</a> but before
anything else. See the example below.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="RETURN_VALUES"><a class="permalink" href="#RETURN_VALUES">RETURN
VALUES</a></h1>
<p class="Pp">The <code class="Fn">ioctl</code>() function returns the value 0
if successful; otherwise the value -1 is returned and the global variable
<var class="Va">errno</var> is set to indicate the error.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="ERRORS"><a class="permalink" href="#ERRORS">ERRORS</a></h1>
<p class="Pp">The <code class="Fn">ioctl</code>() system call with
<code class="Dv">FILEMON_SET_FD</code> will fail if:</p>
<dl class="Bl-tag">
<dt id="EEXIST">[<a class="permalink" href="#EEXIST"><code class="Er">EEXIST</code></a>]</dt>
<dd>The <code class="Nm">filemon</code> handle is already associated with a
file descriptor.</dd>
<dt id="EINVAL">[<a class="permalink" href="#EINVAL"><code class="Er">EINVAL</code></a>]</dt>
<dd>The file descriptor has an invalid type and cannot be used for
tracing.</dd>
<dt id="EBADF">[<a class="permalink" href="#EBADF"><code class="Er">EBADF</code></a>]</dt>
<dd>The file descriptor is invalid or not opened for writing.</dd>
</dl>
<p class="Pp">The <code class="Fn">ioctl</code>() system call with
<code class="Dv">FILEMON_SET_PID</code> will fail if:</p>
<dl class="Bl-tag">
<dt id="ESRCH">[<a class="permalink" href="#ESRCH"><code class="Er">ESRCH</code></a>]</dt>
<dd>No process having the specified process ID exists.</dd>
<dt id="EBUSY">[<a class="permalink" href="#EBUSY"><code class="Er">EBUSY</code></a>]</dt>
<dd>The process ID specified is already being traced and was not the current
process.</dd>
</dl>
<p class="Pp">The <code class="Fn">close</code>() system call on the filemon
file descriptor may fail with the errors from <a class="Xr">write(2)</a> if
any error is encountered while writing the log. It may also fail if:</p>
<dl class="Bl-tag">
<dt id="EFAULT">[<a class="permalink" href="#EFAULT"><code class="Er">EFAULT</code></a>]</dt>
<dd>An invalid address was used for a traced system call argument, resulting
in no log entry for the system call.</dd>
<dt id="ENAMETOOLONG">[<a class="permalink" href="#ENAMETOOLONG"><code class="Er">ENAMETOOLONG</code></a>]</dt>
<dd>An argument for a traced system call was too long, resulting in no log
entry for the system call.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="FILES"><a class="permalink" href="#FILES">FILES</a></h1>
<dl class="Bl-tag">
<dt><span class="Pa">/dev/filemon</span></dt>
<dd style="width: auto;"> </dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
<div class="Bd Li">
<pre>#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <dev/filemon/filemon.h>
#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <unistd.h>
static void
open_filemon(void)
{
pid_t child, wait_rv;
int fm_fd, fm_log;
if ((fm_fd = open("/dev/filemon", O_RDWR | O_CLOEXEC)) == -1)
err(1, "open(\"/dev/filemon\", O_RDWR)");
if ((fm_log = open("filemon.out",
O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, DEFFILEMODE)) == -1)
err(1, "open(filemon.out)");
if (ioctl(fm_fd, FILEMON_SET_FD, &fm_log) == -1)
err(1, "Cannot set filemon log file descriptor");
if ((child = fork()) == 0) {
child = getpid();
if (ioctl(fm_fd, FILEMON_SET_PID, &child) == -1)
err(1, "Cannot set filemon PID");
/* Do something here. */
} else if (child == -1)
err(1, "Cannot fork child");
else {
while ((wait_rv = wait(&child)) == -1 &&
errno == EINTR)
;
if (wait_rv == -1)
err(1, "cannot wait for child");
close(fm_fd);
}
}</pre>
</div>
<p class="Pp">Creates a file named <span class="Pa">filemon.out</span> and
configures the <code class="Nm">filemon</code> device to write the
<code class="Nm">filemon</code> buffer contents to it.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<p class="Pp"><a class="Xr">dtrace(1)</a>, <a class="Xr">ktrace(1)</a>,
<a class="Xr">script(1)</a>, <a class="Xr">truss(1)</a>,
<a class="Xr">ioctl(2)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">A <code class="Nm">filemon</code> device appeared in
<span class="Ux">FreeBSD 9.1</span>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="BUGS"><a class="permalink" href="#BUGS">BUGS</a></h1>
<p class="Pp">Unloading the module may panic the system, thus requires using
<code class="Ic">kldunload -f</code>.</p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">April 19, 2025</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|