Revert the removal of filemon.

This commit is contained in:
maxv 2019-12-23 06:45:36 +00:00
parent 0c3f769417
commit 87107185b5
21 changed files with 1308 additions and 22 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1223 2019/12/18 07:37:17 maxv Exp $
# $NetBSD: mi,v 1.1224 2019/12/23 06:45:36 maxv Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -1114,7 +1114,7 @@
./usr/include/dev/dmover base-c-usr
./usr/include/dev/dtv base-c-usr
./usr/include/dev/eisa base-obsolete obsolete
./usr/include/dev/filemon base-obsolete obsolete
./usr/include/dev/filemon base-c-usr
./usr/include/dev/hdaudio base-c-usr
./usr/include/dev/hdmicec base-c-usr
./usr/include/dev/hid base-c-usr

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.2298 2019/12/18 07:37:17 maxv Exp $
# $NetBSD: mi,v 1.2299 2019/12/23 06:45:36 maxv Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
./etc/mtree/set.comp comp-sys-root
@ -411,7 +411,7 @@
./usr/include/dev/eisa/eisadevs_data.h comp-obsolete obsolete
./usr/include/dev/eisa/eisareg.h comp-obsolete obsolete
./usr/include/dev/eisa/eisavar.h comp-obsolete obsolete
./usr/include/dev/filemon/filemon.h comp-obsolete obsolete
./usr/include/dev/filemon/filemon.h comp-c-include
./usr/include/dev/fssvar.h comp-c-include
./usr/include/dev/hdaudio/hdaudioio.h comp-c-include
./usr/include/dev/hdaudio/hdaudioreg.h comp-c-include

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1666 2019/12/18 07:37:17 maxv Exp $
# $NetBSD: mi,v 1.1667 2019/12/23 06:45:37 maxv Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -1104,7 +1104,7 @@
./usr/share/man/cat4/fast_ipsec.0 man-obsolete obsolete
./usr/share/man/cat4/fd.0 man-sys-catman .cat
./usr/share/man/cat4/fea.0 man-sys-catman .cat
./usr/share/man/cat4/filemon.0 man-obsolete obsolete
./usr/share/man/cat4/filemon.0 man-sys-catman .cat
./usr/share/man/cat4/finsio.0 man-sys-catman .cat
./usr/share/man/cat4/flash.0 man-sys-catman .cat
./usr/share/man/cat4/fms.0 man-sys-catman .cat
@ -4288,7 +4288,7 @@
./usr/share/man/html4/fast_ipsec.html man-obsolete obsolete
./usr/share/man/html4/fd.html man-sys-htmlman html
./usr/share/man/html4/fea.html man-sys-htmlman html
./usr/share/man/html4/filemon.html man-obsolete obsolete
./usr/share/man/html4/filemon.html man-sys-htmlman html
./usr/share/man/html4/finsio.html man-sys-htmlman html
./usr/share/man/html4/flash.html man-sys-htmlman html
./usr/share/man/html4/fms.html man-sys-htmlman html
@ -7244,7 +7244,7 @@
./usr/share/man/man4/fast_ipsec.4 man-obsolete obsolete
./usr/share/man/man4/fd.4 man-sys-man .man
./usr/share/man/man4/fea.4 man-sys-man .man
./usr/share/man/man4/filemon.4 man-obsolete obsolete
./usr/share/man/man4/filemon.4 man-sys-man .man
./usr/share/man/man4/finsio.4 man-sys-man .man
./usr/share/man/man4/flash.4 man-sys-man .man
./usr/share/man/man4/fms.4 man-sys-man .man

View File

@ -1,5 +1,5 @@
#!/bin/sh -
# $NetBSD: MAKEDEV.tmpl,v 1.211 2019/12/18 07:37:17 maxv Exp $
# $NetBSD: MAKEDEV.tmpl,v 1.212 2019/12/23 06:45:37 maxv Exp $
#
# Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
# All rights reserved.
@ -816,6 +816,7 @@ all)
makedev dk24 dk25 dk26 dk27 dk28 dk29 dk30 dk31
makedev ccd0 ccd1 ccd2 ccd3
makedev cgd0 cgd1 cgd2 cgd3
makedev filemon
makedev fss0 fss1 fss2 fss3
makedev md0 md1
makedev raid0 raid1 raid2 raid3 raid4 raid5 raid6 raid7
@ -2181,6 +2182,10 @@ dtrace)
mkdev dtrace/dtrace c %dtrace_chr% 0 600
;;
filemon)
mkdev filemon c %filemon_chr% 0 666
;;
fw[0-9]*)
unit=${i#fw}
for j in 0 1 2 3

View File

@ -1,4 +1,4 @@
# $NetBSD: NetBSD.dist.base,v 1.207 2019/12/18 14:44:16 kamil Exp $
# $NetBSD: NetBSD.dist.base,v 1.208 2019/12/23 06:45:37 maxv Exp $
# @(#)4.4BSD.dist 8.1 (Berkeley) 6/13/93
# Do not customize this file as it may be overwritten on upgrades.
@ -121,6 +121,7 @@
./usr/include/dev/dm
./usr/include/dev/dmover
./usr/include/dev/dtv
./usr/include/dev/filemon
./usr/include/dev/hdaudio
./usr/include/dev/hdmicec
./usr/include/dev/hid

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.691 2019/12/18 07:37:18 maxv Exp $
# $NetBSD: Makefile,v 1.692 2019/12/23 06:45:37 maxv Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@ -23,7 +23,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
dmphy.4 dpt.4 dpti.4 drm.4 drum.4 drvctl.4 dtv.4 dtviic.4 dwctwo.4 \
eap.4 ebus.4 edc.4 elmc.4 emuxki.4 ena.4 envsys.4 ep.4 esh.4 \
esa.4 esiop.4 esm.4 eso.4 et.4 etphy.4 exphy.4 \
fd.4 finsio.4 flash.4 fpa.4 fms.4 fss.4 \
fd.4 filemon.4 finsio.4 flash.4 fpa.4 fms.4 fss.4 \
fujbp.4 full.4 fxp.4 \
gcscaudio.4 gem.4 genfb.4 gentbi.4 geodeide.4 \
glxtphy.4 gpib.4 gpio.4 gpioirq.4 gpiolock.4 gpiopps.4 gpiopwm.4 \

248
share/man/man4/filemon.4 Normal file
View File

@ -0,0 +1,248 @@
.\" $NetBSD: filemon.4,v 1.21 2019/12/23 06:45:37 maxv Exp $
.\"
.\" Copyright (c) 2011, Juniper Networks, Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
.\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 6, 2016
.Dt FILEMON 4
.Os
.Sh NAME
.Nm filemon
.Nd track interesting system calls
.Sh SYNOPSIS
.Cd "pseudo-device filemon"
.Sh DESCRIPTION
In normal situations,
.Nm
is not built-in to the kernel, and a call to open
.Pa /dev/filemon
will auto-load the
.Nm
module (see
.Xr module 7
for more details).
.Pp
(Although not recommended, the
.Nm
facility can be included in a kernel build by adding
.Bd -literal -offset indent
pseudo-device filemon
.Ed
.Pp
to the kernel configuration file.)
.Pp
.Nm
provides a means for tracking the successful system calls performed by
a process and its descendants.
It is used by
.Xr make 1
to track the activities of build scripts, for the purpose of automatically
learning dependencies.
.Pp
The data captured by
.Nm
for the script
.Bd -literal -offset indent
n=`wc -l /etc/motd`; echo "int motd_lines = $n;" > foo.h.new
cmp -s foo.h foo.h.new 2> /dev/null || mv foo.h.new foo.h
.Ed
.Pp
looks like:
.Bd -literal -offset indent
# filemon version 4
# Target pid 24291
V 4
E 29676 /bin/sh
R 29676 /etc/ld.so.conf
R 29676 /lib/libedit.so.2
R 29676 /lib/libterminfo.so.1
R 29676 /lib/libc.so.12
F 29676 4899
E 4899 /usr/bin/wc
R 4899 /etc/ld.so.conf
R 4899 /usr/lib/libc.so.12
R 4899 /etc/motd
X 4899 0
W 29676 foo.h.new
X 29676 0
# Bye bye
E 3250 /bin/sh
R 3250 /etc/ld.so.conf
R 3250 /lib/libedit.so.2
R 3250 /lib/libterminfo.so.1
R 3250 /lib/libc.so.12
W 26673 /dev/null
E 26673 /usr/bin/cmp
R 26673 /etc/ld.so.conf
R 26673 /usr/lib/libc.so.12
X 26673 2
E 576 /bin/mv
R 576 /etc/ld.so.conf
R 576 /lib/libc.so.12
M 576 'foo.h.new' 'foo.h'
X 576 0
X 3250 0
# Bye bye
.Ed
.Pp
Most records follow the format:
.Bd -literal -offset indent
type pid data
.Ed
.Pp
where
.Ar type
is one of the list below, and unless otherwise specified,
.Ar data
is a pathname.
.Bl -tag -width Ds -offset indent
.It Dv C
.Xr chdir 2 .
.It Dv D
.Xr unlink 2 .
.It Dv E
.Xr exec 3 .
.It Dv F
.Xr fork 2 ,
.Xr vfork 2 ;
.Ar data
is the process id of the child.
.It Dv L
.Xr link 2 ,
.Xr symlink 2 ;
.Ar data
is two pathnames.
.It Dv M
.Xr rename 2 ;
.Ar data
is two pathnames.
.It Dv R
.Xr open 2
for read or read-write.
.It Dv W
.Xr open 2
for writing or read-write.
.It Dv X
.Xr exit 3 ;
.Ar data
is the exit status.
.It Dv V
indicates the version of
.Nm .
.El
.Pp
A
.Nm
instance is created by opening
.Pa /dev/filemon .
Then use
.Fn ioctl filemon_fd FILEMON_SET_PID &pid
to identify the target process to monitor, and
.Fn ioctl filemon_fd FILEMON_SET_FD &output_fd
to direct the event log to an already-opened output file.
.Sh FILES
.Bd -literal
/dev/filemon
.Ed
.Sh EXAMPLES
The following example demonstrates the basic usage of
.Nm :
.Pp
.Bd -literal -offset indent
#include <filemon.h>
pid_t pid;
int filemon_fd, temp_fd;
int status;
filemon_fd = open("/dev/filemon", O_RDWR);
temp_fd = mkstemp("/tmp/filemon.XXXXXXX");
/* give filemon the temp file to use */
ioctl(filemon_fd, FILEMON_SET_FD, &temp_fd);
/* children do not need these once they exec */
fcntl(filemon_fd, F_SETFD, FD_CLOEXEC);
fcntl(temp_fd, F_SETFD, FD_CLOEXEC);
pid = fork();
switch(pid) {
case -1:
err(1, "cannot fork");
break;
case 0:
pid = getpid();
/* tell filemon to monitor this process */
ioctl(filemon_fd, FILEMON_SET_PID, &pid);
execvp(...);
_exit(1);
break;
default:
status = wait();
close(filemon_fd);
lseek(temp_fd, SEEK_SET, 0);
/* read the captured syscalls from temp_fd */
close(temp_fd);
break;
}
.Ed
.Pp
The output of
.Nm
is intended to be simple to parse.
It is possible to achieve almost equivalent results with
.Xr dtrace 1
though on many systems this requires elevated privileges.
Also,
.Xr ktrace 1
can capture similar data, but records failed system calls as well as
successful, and is thus more complex to post-process.
.Sh HISTORY
.Nm
was contributed by Juniper Networks.
.Sh SECURITY CONSIDERATIONS
If the monitored process exits, and its pid gets reused,
.Nm
will continue to report events for the new process (and its
descendants) without any authorization checks.
.Pp
Monitoring of a process enables the target process to write to the
tracking process's file descriptor.
.Sh RESTRICTIONS
The
.Nm
facility can only be used to track processes running in the system's
native emulation.
Neither processes using any of the
.Dv COMPAT_xxx
compatibility layers nor
any descendants of such processes can be tracked.
.Pp
If two processes are monitored, and one is a descendant of the other, events
related to the descendant process and its further descendants are delivered
only to the descendant process's monitor.
If a process is being monitored by two instances of
.Nm ,
events will be delivered only to the first instance created (when
.Pa /dev/filemon
was opened), regardless of the order in which the monitoring processes
called
.Fn ioctl fd FILEMON_SET_PID pid .

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.133 2019/12/18 07:37:18 maxv Exp $
# $NetBSD: ALL,v 1.134 2019/12/23 06:45:37 maxv Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.133 $"
#ident "ALL-$Revision: 1.134 $"
maxusers 64 # estimated number of users
@ -1675,6 +1675,8 @@ pseudo-device bcsp # BlueCore Serial Protocol
pseudo-device btuart # Bluetooth HCI UART (H4)
pseudo-device gpiosim 1 # GPIO simulator
pseudo-device filemon # process monitor for make(1)
# a pseudo device needed for Coda # also needs CODA (above)
pseudo-device vcoda # coda minicache <-> venus comm.

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.477 2019/12/18 07:37:18 maxv Exp $
# $NetBSD: ALL,v 1.478 2019/12/23 06:45:37 maxv Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.477 $"
#ident "ALL-$Revision: 1.478 $"
maxusers 64 # estimated number of users
@ -1799,6 +1799,8 @@ pseudo-device bcsp # BlueCore Serial Protocol
pseudo-device btuart # Bluetooth HCI UART (H4)
pseudo-device gpiosim 1 # GPIO simulator
pseudo-device filemon # process monitor for make(1)
# a pseudo device needed for Coda # also needs CODA (above)
pseudo-device vcoda # coda minicache <-> venus comm.

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.1247 2019/12/19 00:23:57 jakllsch Exp $
# $NetBSD: files,v 1.1248 2019/12/23 06:45:37 maxv Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20171118
@ -1544,6 +1544,12 @@ include "net/files.net"
device joy
file dev/ic/joy.c joy needs-flag
# process monitor for make(1)
# normally built as module
defpseudo filemon
file dev/filemon/filemon.c filemon
file dev/filemon/filemon_wrapper.c filemon
#
# General Purpose Input/Output framework
#

View File

@ -1,4 +1,4 @@
# $NetBSD: majors,v 1.91 2019/12/18 07:37:18 maxv Exp $
# $NetBSD: majors,v 1.92 2019/12/23 06:45:37 maxv Exp $
#
# Device majors for Machine-Independent drivers.
#
@ -47,7 +47,7 @@ device-major npf char 198 npf
device-major flash char 199 block 199 flash
device-major dtv char 200 dtv
device-major iic char 201 iic
#obsolete filemon char 202 filemon
device-major filemon char 202 filemon
device-major iscsi char 203 iscsi
device-major tpm char 204 tpm
device-major mfi char 205 mfi

View File

@ -1,6 +1,6 @@
# $NetBSD: Makefile,v 1.42 2019/12/18 07:37:18 maxv Exp $
# $NetBSD: Makefile,v 1.43 2019/12/23 06:45:37 maxv Exp $
SUBDIR= apm ata bluetooth dec dm dmover dtv hdaudio hdmicec hid hpc \
SUBDIR= apm ata bluetooth dec dm dmover dtv filemon hdaudio hdmicec hid hpc \
i2c i2o ic ieee1394 ir isa \
microcode ofw pci pckbport pcmcia pud putter raidframe sbus scsipi \
spi sun tc usb vme wscons

8
sys/dev/filemon/Makefile Normal file
View File

@ -0,0 +1,8 @@
# $NetBSD: Makefile,v 1.3 2019/12/23 06:45:38 maxv Exp $
INCSDIR= /usr/include/dev/filemon
# Only install includes which are used by userland
INCS= filemon.h
.include <bsd.kinc.mk>

445
sys/dev/filemon/filemon.c Normal file
View File

@ -0,0 +1,445 @@
/* $NetBSD: filemon.c,v 1.33 2019/12/23 06:45:38 maxv Exp $ */
/*
* Copyright (c) 2010, Juniper Networks, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: filemon.c,v 1.33 2019/12/23 06:45:38 maxv Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/conf.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/fcntl.h>
#include <sys/rwlock.h>
#include <sys/condvar.h>
#include <sys/lwp.h>
#include <sys/proc.h>
#include <sys/kmem.h>
#include <sys/syslog.h>
#include <sys/kauth.h>
#include "filemon.h"
#include "ioconf.h"
MODULE(MODULE_CLASS_DRIVER, filemon, NULL);
static dev_type_open(filemon_open);
struct cdevsw filemon_cdevsw = {
.d_open = filemon_open,
.d_close = noclose,
.d_read = noread,
.d_write = nowrite,
.d_ioctl = noioctl,
.d_stop = nostop,
.d_tty = notty,
.d_poll = nopoll,
.d_mmap = nommap,
.d_kqfilter = nokqfilter,
.d_discard = nodiscard,
.d_flag = D_MPSAFE
};
static int filemon_ioctl(struct file *, u_long, void *);
static int filemon_close(struct file *);
static const struct fileops filemon_fileops = {
.fo_name = "filemon",
.fo_ioctl = filemon_ioctl,
.fo_close = filemon_close,
.fo_read = fbadop_read,
.fo_write = fbadop_write,
.fo_fcntl = fnullop_fcntl,
.fo_poll = fnullop_poll,
.fo_stat = fbadop_stat,
.fo_kqfilter = fnullop_kqfilter,
};
static krwlock_t filemon_mtx;
static TAILQ_HEAD(, filemon) filemons_inuse =
TAILQ_HEAD_INITIALIZER(filemons_inuse);
#ifdef DEBUG
static int logLevel = LOG_DEBUG;
#endif
void
filemon_output(struct filemon * filemon, char *msg, size_t len)
{
struct uio auio;
struct iovec aiov;
if (filemon->fm_fp == NULL)
return;
aiov.iov_base = msg;
aiov.iov_len = len;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_resid = len;
auio.uio_rw = UIO_WRITE;
auio.uio_offset = (off_t) - 1;
uio_setup_sysspace(&auio);
#ifdef DEBUG
{
char *cp;
int x = 16;
cp = strchr(msg, '\n');
if (cp && cp - msg <= 16)
x = (cp - msg) - 2;
log(logLevel, "filemon_output:('%.*s%s'", x,
(x < 16) ? "..." : "", msg);
}
#endif
(*filemon->fm_fp->f_ops->fo_write) (filemon->fm_fp,
&(filemon->fm_fp->f_offset),
&auio, curlwp->l_cred, FOF_UPDATE_OFFSET);
}
void
filemon_printf(struct filemon *filemon, const char *fmt, ...)
{
size_t len;
va_list ap;
va_start(ap, fmt);
len = vsnprintf(filemon->fm_msgbufr, sizeof(filemon->fm_msgbufr),
fmt, ap);
va_end(ap);
if (len > sizeof(filemon->fm_msgbufr))
len = sizeof(filemon->fm_msgbufr);
filemon_output(filemon, filemon->fm_msgbufr, len);
}
static void
filemon_comment(struct filemon * filemon)
{
filemon_printf(filemon, "# filemon version %d\n# Target pid %d\nV %d\n",
FILEMON_VERSION, curproc->p_pid, FILEMON_VERSION);
}
static struct filemon *
filemon_pid_check(struct proc * p)
{
struct filemon *filemon;
struct proc * lp;
KASSERT(p != NULL);
if (!TAILQ_EMPTY(&filemons_inuse)) {
/*
* make sure p cannot exit
* until we have moved on to p_pptr
*/
rw_enter(&p->p_reflock, RW_READER);
while (p) {
TAILQ_FOREACH(filemon, &filemons_inuse, fm_link) {
if (p->p_pid == filemon->fm_pid) {
rw_exit(&p->p_reflock);
return (filemon);
}
}
lp = p;
p = p->p_pptr;
/* lock parent before releasing child */
if (p != NULL)
rw_enter(&p->p_reflock, RW_READER);
rw_exit(&lp->p_reflock);
}
}
return (NULL);
}
/*
* return exclusive access to a filemon struct
*/
struct filemon *
filemon_lookup(struct proc * p)
{
struct filemon *filemon;
rw_enter(&filemon_mtx, RW_READER);
filemon = filemon_pid_check(p);
if (filemon) {
rw_enter(&filemon->fm_mtx, RW_WRITER);
}
rw_exit(&filemon_mtx);
return filemon;
}
static struct filemon *
filemon_fp_data(struct file * fp, int lck)
{
struct filemon *filemon;
rw_enter(&filemon_mtx, RW_READER);
filemon = fp->f_data;
if (filemon && lck) {
rw_enter(&filemon->fm_mtx, lck);
}
rw_exit(&filemon_mtx);
return filemon;
}
static int n_open = 0;
static int
filemon_open(dev_t dev, int oflags __unused, int mode __unused,
struct lwp * l __unused)
{
struct filemon *filemon;
struct file *fp;
int error, fd;
/* falloc() will fill in the descriptor for us. */
if ((error = fd_allocfile(&fp, &fd)) != 0)
return error;
filemon = kmem_alloc(sizeof(struct filemon), KM_SLEEP);
rw_init(&filemon->fm_mtx);
filemon->fm_fp = NULL;
filemon->fm_pid = curproc->p_pid;
rw_enter(&filemon_mtx, RW_WRITER);
TAILQ_INSERT_TAIL(&filemons_inuse, filemon, fm_link);
n_open++;
rw_exit(&filemon_mtx);
return fd_clone(fp, fd, oflags, &filemon_fileops, filemon);
}
static int
filemon_close(struct file * fp)
{
struct filemon *filemon;
#ifdef DEBUG
log(logLevel, "filemon_close()");
#endif
/*
* Follow the same lock order as filemon_lookup()
* and filemon_fp_data() but hold exclusive access to
* filemon_mtx until we are done.
*/
rw_enter(&filemon_mtx, RW_WRITER);
filemon = fp->f_data;
if (!filemon) {
rw_exit(&filemon_mtx);
return EBADF;
}
/* ensure that filemon_lookup() will now fail */
TAILQ_REMOVE(&filemons_inuse, filemon, fm_link);
n_open--;
/* ensure that filemon_fp_data() will now fail */
fp->f_data = NULL;
/*
* once we have exclusive access, it should never be used again
*/
rw_enter(&filemon->fm_mtx, RW_WRITER);
if (filemon->fm_fp) {
closef(filemon->fm_fp); /* release our reference */
filemon->fm_fp = NULL;
}
rw_exit(&filemon->fm_mtx);
rw_destroy(&filemon->fm_mtx);
kmem_free(filemon, sizeof(struct filemon));
rw_exit(&filemon_mtx);
return (0);
}
static int
filemon_ioctl(struct file * fp, u_long cmd, void *data)
{
int error = 0;
int fd;
struct filemon *filemon;
struct proc *tp;
#ifdef DEBUG
log(logLevel, "filemon_ioctl(%lu)", cmd);
#endif
/*
* this ensures we cannot get filemon if it is closing.
*/
filemon = filemon_fp_data(fp, RW_WRITER);
if (!filemon)
return EBADF;
/* filemon_fp_data() has locked the entry - make sure to unlock! */
switch (cmd) {
case FILEMON_SET_FD:
/* Set the output file descriptor. */
/* First, release any current output file descriptor */
if (filemon->fm_fp)
closef(filemon->fm_fp);
/* Now set up the new one */
fd = *((int *) data);
if ((filemon->fm_fp = fd_getfile2(curproc, fd)) == NULL) {
error = EBADF;
break;
}
if ((filemon->fm_fp->f_flag & FWRITE) == 0) {
closef(filemon->fm_fp);
filemon->fm_fp = NULL;
return (EBADF);
}
/* Write the file header. */
filemon_comment(filemon);
break;
case FILEMON_SET_PID:
/* Set the monitored process ID - if allowed. */
mutex_enter(proc_lock);
tp = proc_find(*((pid_t *) data));
if (tp == NULL ||
tp->p_emul != &emul_netbsd) {
error = ESRCH;
mutex_exit(proc_lock);
break;
}
error = kauth_authorize_process(curproc->p_cred,
KAUTH_PROCESS_CANSEE, tp,
KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
if (!error) {
filemon->fm_pid = tp->p_pid;
}
mutex_exit(proc_lock);
break;
default:
error = EINVAL;
break;
}
rw_exit(&filemon->fm_mtx);
return (error);
}
static int
filemon_load(void *dummy __unused)
{
rw_init(&filemon_mtx);
/* Install the syscall wrappers. */
return filemon_wrapper_install();
}
/*
* If this gets called we are linked into the kernel
*/
void
filemonattach(int num)
{
/*
* Don't call filemon_load() here - it will be called from
* filemon_modcmd() during module initialization.
*/
#if 0
filemon_load(NULL);
#endif
}
static int
filemon_unload(void)
{
int error = 0;
rw_enter(&filemon_mtx, RW_WRITER);
if (TAILQ_FIRST(&filemons_inuse) != NULL)
error = EBUSY;
else {
/* Deinstall the syscall wrappers. */
error = filemon_wrapper_deinstall();
}
rw_exit(&filemon_mtx);
if (error == 0) {
rw_destroy(&filemon_mtx);
}
return (error);
}
static int
filemon_modcmd(modcmd_t cmd, void *data)
{
int error = 0;
#ifdef _MODULE
int bmajor = -1;
int cmajor = -1;
#endif
switch (cmd) {
case MODULE_CMD_INIT:
#ifdef DEBUG
logLevel = LOG_INFO;
#endif
error = filemon_load(data);
#ifdef _MODULE
if (!error)
error = devsw_attach("filemon", NULL, &bmajor,
&filemon_cdevsw, &cmajor);
#endif
break;
case MODULE_CMD_FINI:
error = filemon_unload();
#ifdef _MODULE
if (!error)
error = devsw_detach(NULL, &filemon_cdevsw);
#endif
break;
case MODULE_CMD_STAT:
log(LOG_INFO, "filemon: open=%d", n_open);
break;
default:
error = ENOTTY;
break;
}
return (error);
}

62
sys/dev/filemon/filemon.h Normal file
View File

@ -0,0 +1,62 @@
/* $NetBSD: filemon.h,v 1.11 2019/12/23 06:45:38 maxv Exp $ */
/*
* Copyright (c) 2010, Juniper Networks, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FILEMON_SET_FD
#include <sys/ioccom.h>
#ifndef _PATH_FILEMON
#define _PATH_FILEMON "/dev/filemon"
#endif
#define FILEMON_SET_FD _IOWR('S', 1, int)
#define FILEMON_SET_PID _IOWR('S', 2, pid_t)
#define FILEMON_VERSION 5
#ifdef _KERNEL
struct filemon {
pid_t fm_pid; /* The process ID being monitored. */
char fm_fname1[MAXPATHLEN];/* Temporary filename buffer. */
char fm_fname2[MAXPATHLEN];/* Temporary filename buffer. */
char fm_msgbufr[32 + 2 * MAXPATHLEN]; /* Output message buffer. */
struct file *fm_fp; /* Output file pointer. */
krwlock_t fm_mtx; /* Lock mutex for this filemon. */
TAILQ_ENTRY(filemon) fm_link; /* Link into the in-use list. */
};
struct hijack {
int hj_index;
sy_call_t *hj_funcs[2]; /* [0] = original, [1] = hijack */
};
struct filemon * filemon_lookup(struct proc *);
void filemon_output(struct filemon *, char *, size_t);
int syscall_hijack(struct sysent *, const struct hijack *, bool);
int filemon_wrapper_install(void);
int filemon_wrapper_deinstall(void);
void filemon_printf(struct filemon *, const char *, ...) __printflike(2, 3);
#endif
#endif

View File

@ -0,0 +1,456 @@
/* $NetBSD: filemon_wrapper.c,v 1.14 2019/12/23 06:45:38 maxv Exp $ */
/*
* Copyright (c) 2010, Juniper Networks, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: filemon_wrapper.c,v 1.14 2019/12/23 06:45:38 maxv Exp $");
#include <sys/param.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/lwp.h>
#include <sys/proc.h>
#include <sys/syscall.h>
#include <sys/syscallargs.h>
#include "filemon.h"
static int filemon_wrapper_chdir(struct lwp *, const struct sys_chdir_args *,
register_t *);
static int filemon_wrapper_execve(struct lwp *, struct sys_execve_args *,
register_t *);
static int filemon_wrapper_sys_exit(struct lwp *, struct sys_exit_args *,
register_t *);
static int filemon_wrapper_fork(struct lwp *, const void *, register_t *);
static int filemon_wrapper_link(struct lwp *, struct sys_link_args *,
register_t *);
static int filemon_wrapper_open(struct lwp *, struct sys_open_args *,
register_t *);
static int filemon_wrapper_openat(struct lwp *, struct sys_openat_args *,
register_t *);
static int filemon_wrapper_rename(struct lwp *, struct sys_rename_args *,
register_t *);
static int filemon_wrapper_symlink(struct lwp *, struct sys_symlink_args *,
register_t *);
static int filemon_wrapper_unlink(struct lwp *, struct sys_unlink_args *,
register_t *);
static int filemon_wrapper_vfork(struct lwp *, const void *, register_t *);
const struct hijack filemon_hijack[] = {
{ SYS_chdir,
{ (sy_call_t *)sys_chdir, (sy_call_t *)filemon_wrapper_chdir } },
{ SYS_execve,
{ (sy_call_t *)sys_execve, (sy_call_t *)filemon_wrapper_execve } },
{ SYS_exit,
{ (sy_call_t *)sys_exit, (sy_call_t *)filemon_wrapper_sys_exit } },
{ SYS_fork,
{ (sy_call_t *)sys_fork, (sy_call_t *)filemon_wrapper_fork } },
{ SYS_link,
{ (sy_call_t *)sys_link, (sy_call_t *)filemon_wrapper_link } },
{ SYS_open,
{ (sy_call_t *)sys_open, (sy_call_t *)filemon_wrapper_open } },
{ SYS_openat,
{ (sy_call_t *)sys_openat, (sy_call_t *)filemon_wrapper_openat } },
{ SYS_rename,
{ (sy_call_t *)sys_rename, (sy_call_t *)filemon_wrapper_rename } },
{ SYS_symlink,
{ (sy_call_t *)sys_symlink, (sy_call_t *)filemon_wrapper_symlink } },
{ SYS_unlink,
{ (sy_call_t *)sys_unlink, (sy_call_t *)filemon_wrapper_unlink } },
{ SYS_vfork,
{ (sy_call_t *)sys_vfork, (sy_call_t *)filemon_wrapper_vfork } },
{ -1, {NULL, NULL } }
};
int
syscall_hijack(struct sysent *sv_table, const struct hijack *hj_pkg,
bool restore)
{
int from, to;
const struct hijack *entry;
if (restore) /* Which entry should currently match? */
from = 1;
else
from = 0;
to = 1 - from; /* Which entry will we replace with? */
KASSERT(kernconfig_is_held());
/* First, make sure that all of the old values match */
for (entry = hj_pkg; entry->hj_index >= 0; entry++)
if (sv_table[entry->hj_index].sy_call != entry->hj_funcs[from])
break;
if (entry->hj_index >= 0)
return EBUSY;
/* Now replace the old values with the new ones */
for (entry = hj_pkg; entry->hj_index >= 0; entry++)
sv_table[entry->hj_index].sy_call = entry->hj_funcs[to];
return 0;
}
static int
filemon_wrapper_chdir(struct lwp * l, const struct sys_chdir_args * uap,
register_t * retval)
{
int error;
size_t done;
struct filemon *filemon;
if ((error = sys_chdir(l, uap, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
error = copyinstr(SCARG(uap, path), filemon->fm_fname1,
sizeof(filemon->fm_fname1), &done);
if (error)
goto out;
filemon_printf(filemon, "C %d %s\n",
curproc->p_pid, filemon->fm_fname1);
out:
rw_exit(&filemon->fm_mtx);
return 0;
}
static int
filemon_wrapper_execve(struct lwp * l, struct sys_execve_args * uap,
register_t * retval)
{
char fname[MAXPATHLEN];
int error, cerror;
size_t done;
struct filemon *filemon;
cerror = copyinstr(SCARG(uap, path), fname, sizeof(fname), &done);
if ((error = sys_execve(l, uap, retval)) != EJUSTRETURN)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return EJUSTRETURN;
if (cerror)
goto out;
filemon_printf(filemon, "E %d %s\n", curproc->p_pid, fname);
out:
rw_exit(&filemon->fm_mtx);
return EJUSTRETURN;
}
static int
filemon_wrapper_fork(struct lwp * l, const void *v, register_t * retval)
{
int error;
struct filemon *filemon;
if ((error = sys_fork(l, v, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
filemon_printf(filemon, "F %d %ld\n", curproc->p_pid, (long) retval[0]);
rw_exit(&filemon->fm_mtx);
return 0;
}
static int
filemon_wrapper_vfork(struct lwp * l, const void *v, register_t * retval)
{
int error;
struct filemon *filemon;
if ((error = sys_vfork(l, v, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
filemon_printf(filemon, "F %d %ld\n", curproc->p_pid, (long) retval[0]);
rw_exit(&filemon->fm_mtx);
return 0;
}
static void
filemon_flags(struct filemon * filemon, int f)
{
if (f & O_RDWR) {
/* we want a separate R record */
filemon_printf(filemon, "R %d %s\n", curproc->p_pid,
filemon->fm_fname1);
}
filemon_printf(filemon, "%c %d %s\n", (f & O_ACCMODE) ? 'W' : 'R',
curproc->p_pid, filemon->fm_fname1);
}
static int
filemon_wrapper_open(struct lwp * l, struct sys_open_args * uap,
register_t * retval)
{
int error;
size_t done;
struct filemon *filemon;
if ((error = sys_open(l, uap, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
error = copyinstr(SCARG(uap, path), filemon->fm_fname1,
sizeof(filemon->fm_fname1), &done);
if (error)
goto out;
filemon_flags(filemon, SCARG(uap, flags));
out:
rw_exit(&filemon->fm_mtx);
return 0;
}
static int
filemon_wrapper_openat(struct lwp * l, struct sys_openat_args * uap,
register_t * retval)
{
int error;
size_t done;
struct filemon *filemon;
if ((error = sys_openat(l, uap, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
error = copyinstr(SCARG(uap, path), filemon->fm_fname1,
sizeof(filemon->fm_fname1), &done);
if (error)
goto out;
if (filemon->fm_fname1[0] != '/' && SCARG(uap, fd) != AT_FDCWD) {
/*
* Rats we cannot just treat like open.
* Output an 'A' record as a clue.
*/
filemon_printf(filemon, "A %d %s\n", curproc->p_pid,
filemon->fm_fname1);
}
filemon_flags(filemon, SCARG(uap, oflags));
out:
rw_exit(&filemon->fm_mtx);
return 0;
}
static int
filemon_wrapper_rename(struct lwp * l, struct sys_rename_args * uap,
register_t * retval)
{
int error;
size_t done;
struct filemon *filemon;
if ((error = sys_rename(l, uap, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
error = copyinstr(SCARG(uap, from), filemon->fm_fname1,
sizeof(filemon->fm_fname1), &done);
if (error)
goto out;
error = copyinstr(SCARG(uap, to), filemon->fm_fname2,
sizeof(filemon->fm_fname2), &done);
if (error)
goto out;
filemon_printf(filemon, "M %d '%s' '%s'\n", curproc->p_pid,
filemon->fm_fname1, filemon->fm_fname2);
out:
rw_exit(&filemon->fm_mtx);
return 0;
}
static int
filemon_wrapper_link(struct lwp * l, struct sys_link_args * uap,
register_t * retval)
{
int error;
size_t done;
struct filemon *filemon;
if ((error = sys_link(l, uap, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
error = copyinstr(SCARG(uap, path), filemon->fm_fname1,
sizeof(filemon->fm_fname1), &done);
if (error)
goto out;
error = copyinstr(SCARG(uap, link), filemon->fm_fname2,
sizeof(filemon->fm_fname2), &done);
if (error)
goto out;
filemon_printf(filemon, "L %d '%s' '%s'\n", curproc->p_pid,
filemon->fm_fname1, filemon->fm_fname2);
out:
rw_exit(&filemon->fm_mtx);
return 0;
}
static int
filemon_wrapper_symlink(struct lwp * l, struct sys_symlink_args * uap,
register_t * retval)
{
int error;
size_t done;
struct filemon *filemon;
if ((error = sys_symlink(l, uap, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
error = copyinstr(SCARG(uap, path), filemon->fm_fname1,
sizeof(filemon->fm_fname1), &done);
if (error)
goto out;
error = copyinstr(SCARG(uap, link), filemon->fm_fname2,
sizeof(filemon->fm_fname2), &done);
if (error)
goto out;
filemon_printf(filemon, "L %d '%s' '%s'\n", curproc->p_pid,
filemon->fm_fname1, filemon->fm_fname2);
out:
rw_exit(&filemon->fm_mtx);
return 0;
}
static int
filemon_wrapper_sys_exit(struct lwp * l, struct sys_exit_args * uap,
register_t * retval)
{
struct filemon *filemon;
filemon = filemon_lookup(curproc);
if (filemon) {
filemon_printf(filemon, "X %d %d\n",
curproc->p_pid, SCARG(uap, rval));
/* Check if the monitored process is about to exit. */
if (filemon->fm_pid == curproc->p_pid)
filemon_printf(filemon, "# Bye bye\n");
rw_exit(&filemon->fm_mtx);
}
return sys_exit(l, uap, retval);
}
static int
filemon_wrapper_unlink(struct lwp * l, struct sys_unlink_args * uap,
register_t * retval)
{
int error;
size_t done;
struct filemon *filemon;
if ((error = sys_unlink(l, uap, retval)) != 0)
return error;
filemon = filemon_lookup(curproc);
if (filemon == NULL)
return 0;
error = copyinstr(SCARG(uap, path), filemon->fm_fname1,
sizeof(filemon->fm_fname1), &done);
if (error)
goto out;
filemon_printf(filemon, "D %d %s\n",
curproc->p_pid, filemon->fm_fname1);
out:
rw_exit(&filemon->fm_mtx);
return 0;
}
int
filemon_wrapper_install(void)
{
int error;
struct sysent *sv_table = emul_netbsd.e_sysent;
kernconfig_lock();
error = syscall_hijack(sv_table, filemon_hijack, false);
kernconfig_unlock();
return error;
}
int
filemon_wrapper_deinstall(void)
{
int error;
struct sysent *sv_table = emul_netbsd.e_sysent;
kernconfig_lock();
error = syscall_hijack(sv_table, filemon_hijack, true);
kernconfig_unlock();
return error;
}

22
sys/dev/filemon/mknod-sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
# Note that filemon.kmod needs the 6.x version of modload.
Error() {
echo "ERROR: $@" >&2; exit 1
}
major=`sysctl kern.drivers | tr ',' '\012' | sed -n '/filemon/s,.*\[\([0-9][0-9]*\).*,\1,p'`
[ ${major:-0} -gt 0 ] || Error filemon not loaded
dev=/dev/filemon
if [ -c $dev ]; then
x=`'ls' -l $dev`
case "$x" in
*" $major,"*) exit 0;;
esac
rm -f $dev
fi
mknod -m 666 $dev c $major 0

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.232 2019/12/18 07:37:18 maxv Exp $
# $NetBSD: Makefile,v 1.233 2019/12/23 06:45:38 maxv Exp $
.include <bsd.own.mk>
@ -54,6 +54,7 @@ SUBDIR+= exec_script
SUBDIR+= fdesc
SUBDIR+= ffs
SUBDIR+= filecore
SUBDIR+= filemon
SUBDIR+= flash
SUBDIR+= fss
SUBDIR+= gpio

View File

@ -0,0 +1,20 @@
# $NetBSD: Makefile,v 1.6 2019/12/23 06:45:38 maxv Exp $
.include "../Makefile.inc"
.PATH: ${S}/dev/filemon
KMOD = filemon
IOCONF= filemon.ioconf
SRCS = filemon.c filemon_wrapper.c
NOMAN = no
COPTS.filemon_wrapper.c+= ${GCC_NO_CAST_FUNCTION_TYPE}
# Due to security concerns, we don't install the filemon module. We
# do, however, want to keep building it to prevent bit-rot. Define
# an empty install target for this.
kmodinstall:
.include <bsd.kmodule.mk>

View File

@ -0,0 +1,7 @@
# $NetBSD: filemon.ioconf,v 1.3 2019/12/23 06:45:38 maxv Exp $
ioconf filemon
include "conf/files"
pseudo-device filemon

View File

@ -1140,6 +1140,7 @@ fhstatvfs
fhtovp
fileassoc
fileio
filemon
filt
fincore
fingerd