FreeBSD 7.1
Makefile
SRCS = rmdir.c vn_help.c main.c vnode_if.h
KMOD = fsmon
KO = $(KMOD).ko
KLDMOD = t
WERROR =
.include <bsd.kmod.mk>
main.c 模块主文件
#include "inc.h"
static int
load (struct module *module, int cmd, void *arg)
{
int error = 0;
switch( cmd ) {
case MOD_LOAD:
uprintf( "%s module was loaded. /n", MOD_NAME );
//sysent[SYS_rmdir].sy_call = (sy_call_t *)new_rmdir;
//sysent[SYS_mkdir].sy_call = (sy_call_t *)new_mkdir;
sysent[SYS_open].sy_call = (sy_call_t *)new_open;
break;
case MOD_UNLOAD:
uprintf( "%s module was unloaded. /n", MOD_NAME );
//sysent[SYS_rmdir].sy_call = (sy_call_t *)rmdir;
//sysent[SYS_mkdir].sy_call = (sy_call_t *)mkdir;
sysent[SYS_open].sy_call = (sy_call_t *)open;
break;
default:
error = EINVAL;
break;
}
return error;
}
static moduledata_t fsmon_mod = {
"fsmon",
load,
NULL
};
DECLARE_MODULE(fsmon, fsmon_mod, SI_SUB_KLD,SI_ORDER_ANY);
open.c 拦截open系统调用
#include "inc.h"
static char old_path[MAXPATHLEN];
int
new_open(td, uap)
struct thread *td;
register struct open_args /* {
char *path;
int flags;
int mode;
} */ *uap;
{
struct vnode *vp, *dvp = NULL;
int error;
struct nameidata nd, *ndp;
int vfslocked;
char *dlep = NULL;
char *flep = NULL;
char *nameptr = NULL;
char *dirptr = NULL;
int fmode = 0, mpsafe;
int locked = 0;
fmode = FFLAGS(uap->flags);
ndp = &nd;
mpsafe = ndp->ni_cnd.cn_flags & MPSAFE;
vfslocked = 0;
NDINIT(ndp, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, UIO_USERSPACE, uap->path, td);
if (fmode & O_CREAT) {
ndp->ni_cnd.cn_nameiop = CREATE;
ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF |
MPSAFE | AUDITVNODE1;
if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
ndp->ni_cnd.cn_flags |= FOLLOW;
bwillwrite();
if ((error = namei(ndp)) != 0)
return (error);
vfslocked = NDHASGIANT(ndp);
if (!mpsafe)
ndp->ni_cnd.cn_flags &= ~MPSAFE;
if (ndp->ni_vp == NULL) {
dvp = ndp->ni_dvp;
vp = NULL;
locked = 0;
vput(ndp->ni_dvp);
VFS_UNLOCK_GIANT(vfslocked);
NDFREE(ndp, NDF_ONLY_PNBUF);
}
else {
if (ndp->ni_dvp == ndp->ni_vp)
vrele(ndp->ni_dvp);
else
vput(ndp->ni_dvp);
dvp = ndp->ni_dvp;
vp = ndp->ni_vp;
locked = 1;
if (fmode & O_EXCL) {
error = EEXIST;
goto bad;
}
}
}
else {
ndp->ni_cnd.cn_nameiop = LOOKUP;
ndp->ni_cnd.cn_flags = ISOPEN |
((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) |
LOCKLEAF | MPSAFE | AUDITVNODE1;
if ((error = namei(ndp)) != 0)
return (error);
if (!mpsafe)
ndp->ni_cnd.cn_flags &= ~MPSAFE;
vfslocked = NDHASGIANT(ndp);
dvp = ndp->ni_dvp;
vp = ndp->ni_vp;
locked = 1;
}
if ( vp ) {
if (vp->v_type == VLNK) {
error = EMLINK;
goto bad;
}
if (vp->v_type == VSOCK) {
error = EOPNOTSUPP;
goto bad;
}
if (fmode & (FWRITE | O_TRUNC)) {
if (vp->v_type == VDIR) {
error = EISDIR;
goto bad;
}
}
}
if ( dvp ) {
error = vn_fullpath( td, dvp, &dlep, &flep );
if ( !error ) {
//uprintf( "path = %s/n", dlep );
strncpy( old_path, dlep, MAXPATHLEN );
}
else {
uprintf( "%s: vn_fullpath call fail. return %d/n", __func__, error );
//uprintf( "old_path = %s /n", old_path );
}
//
dirptr = old_path;
if ( nd.ni_cnd.cn_namelen ) {
nameptr = nd.ni_cnd.cn_nameptr;
}
else {
nameptr = "";
}
if ( fmode & O_CREAT ) {
uprintf( "open %s/%s for create/n", dirptr, nameptr );
}
else {
if ( fmode & (FWRITE | O_TRUNC | O_APPEND) ) {
uprintf( "open %s/%s for write/n", dirptr, nameptr );
}
else {
uprintf( "open %s/%s/n", dirptr, nameptr );
}
}
if ( flep ) {
free( flep, M_TEMP );
}
error = 0;
}
if ( locked ) {
NDFREE(ndp, NDF_ONLY_PNBUF);
if ( vp )
vput(vp);
VFS_UNLOCK_GIANT(vfslocked);
}
return kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode);
bad:
NDFREE(ndp, NDF_ONLY_PNBUF);
if ( vp )
vput(vp);
VFS_UNLOCK_GIANT(vfslocked);
return error;
}
in.h 公共头文件
#ifndef _INC_H
#define _INC_H
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/sysent.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/sysproto.h>
#include <sys/namei.h>
#include <sys/filedesc.h>
#include <sys/kernel.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filio.h>
#include <sys/limits.h>
#include <sys/linker.h>
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/dirent.h>
#include <sys/jail.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
#include <machine/stdarg.h>
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/uma.h>
#define MOD_NAME "fsmon"
int new_open(struct thread *, struct open_args *);
#endif