天天看点

FreeBSD中替换系统调用监视系统文件打开记录

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