From owner-p4-projects@FreeBSD.ORG Fri Jun 25 00:46:38 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B0902106566B; Fri, 25 Jun 2010 00:46:38 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 720A71065672 for ; Fri, 25 Jun 2010 00:46:38 +0000 (UTC) (envelope-from gpf@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 5EF8A8FC19 for ; Fri, 25 Jun 2010 00:46:38 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o5P0kbZW099316 for ; Fri, 25 Jun 2010 00:46:37 GMT (envelope-from gpf@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o5P0ka6K099312 for perforce@freebsd.org; Fri, 25 Jun 2010 00:46:36 GMT (envelope-from gpf@FreeBSD.org) Date: Fri, 25 Jun 2010 00:46:36 GMT Message-Id: <201006250046.o5P0ka6K099312@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gpf@FreeBSD.org using -f From: Efstratios Karatzas To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 180201 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jun 2010 00:46:38 -0000 http://p4web.freebsd.org/@@180201?ac=10 Change 180201 by gpf@gpf_desktop on 2010/06/25 00:45:44 experimental nfs server: - added support for more nfs v2&3 rpcs - actually everything besides rename, link, null & noop. Tested and everything seems to be working fine besides mknod rpc; can't audit paths for this one. This is actually because after creating a local fifo, I noticed that VOP_GETPARENT() does not get called for the UFS fs that the named pipe I create seems to reside in, but for some other fs that does not have this particular VOP as I've implemented it only for UFS & ZFS. Should probably look into that. - some AUDIT_ARG_VNODE1()s where called without having a locked vp - fixed - relocated the wrapper function to the vn_fullpath() KPIs to nfs_nfsdsubs.c; not sure if this is the right place but it will do for the moment. - probably some more minor fixes but it's 3:44 am and my brain is toasted Affected files ... .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfs/nfs_var.h#3 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdport.c#5 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdserv.c#5 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdsocket.c#5 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdsubs.c#2 edit Differences ... ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfs/nfs_var.h#3 (text+ko) ==== @@ -308,6 +308,7 @@ NFSPATHLEN_T *); void nfsd_init(void); int nfsd_checkrootexp(struct nfsrv_descript *); +void nfsrv_auditpath(vnode_t vp, vnode_t dvp, char *fname, fhandle_t *fhp, int n); /* nfs_clvfsops.c */ ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdport.c#5 (text+ko) ==== @@ -724,7 +724,7 @@ if (!error && ndp->ni_vp == NULL) { if (nvap->na_type == VREG || nvap->na_type == VSOCK) { vrele(ndp->ni_startdir); - AUDIT_ARG_MODE(nvap->na_vattr.va_mode); + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); @@ -831,9 +831,9 @@ vput(ndp->ni_dvp); return (NFSERR_BADTYPE); } + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); if (vtyp == VSOCK) { - vrele(ndp->ni_startdir); - AUDIT_ARG_MODE(nvap->na_vattr.va_mode); + vrele(ndp->ni_startdir); error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); @@ -846,7 +846,6 @@ vput(ndp->ni_dvp); return (error); } - AUDIT_ARG_MODE(nvap->na_vattr.va_mode); error = VOP_MKNOD(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); @@ -858,6 +857,7 @@ * see any reason to do the lookup. */ } + return (error); } @@ -884,6 +884,8 @@ &nvap->na_vattr); vput(ndp->ni_dvp); nfsvno_relpathbuf(ndp); + if (!error) + AUDIT_ARG_VNODE1(ndp->ni_vp); return (error); } @@ -896,7 +898,9 @@ struct nfsexstuff *exp) { int error = 0; - + + AUDIT_ARG_UPATH2(curthread, pathcp); + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); if (ndp->ni_vp) { vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); @@ -907,20 +911,21 @@ vrele(ndp->ni_vp); return (EEXIST); } - - AUDIT_ARG_MODE(nvap->na_vattr.va_mode); + error = VOP_SYMLINK(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr, pathcp); vput(ndp->ni_dvp); vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); + if (!error) + AUDIT_ARG_VNODE1(ndp->ni_vp); /* * Although FreeBSD still had the lookup code in * it for 7/current, there doesn't seem to be any * point, since VOP_SYMLINK() returns the ni_vp. * Just vput it for v2. */ - if (!not_v2 && !error) + if (!not_v2 && !error) vput(ndp->ni_vp); return (error); } @@ -1163,8 +1168,9 @@ if (ndp->ni_dvp == vp) vrele(ndp->ni_dvp); else - vput(ndp->ni_dvp); + vput(ndp->ni_dvp); NFSVOPUNLOCK(vp, 0, p); + nfsrv_auditpath(NULL, ndp->ni_dvp, ndp->ni_cnd.cn_pnbuf, NULL, 1); } else { if (ndp->ni_dvp == ndp->ni_vp) vrele(ndp->ni_dvp); ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdserv.c#5 (text+ko) ==== @@ -1014,6 +1014,7 @@ nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); vput(vp); + nfsrv_auditpath(vp, NULL, NULL, &fh, 1); if (!nd->nd_repstat) { tverf[0] = nva.na_atime.tv_sec; tverf[1] = nva.na_atime.tv_nsec; @@ -1232,8 +1233,7 @@ nd->nd_repstat = nfsvno_mknod(&named, &nva, nd->nd_cred, p); if (!nd->nd_repstat) { vp = named.ni_vp; - if (vp != NULL) - AUDIT_ARG_VNODE1(vp); + AUDIT_ARG_VNODE1(vp); nfsrv_fixattr(nd, vp, &nva, aclp, p, &attrbits, exp); nd->nd_repstat = nfsvno_getfh(vp, fhp, p, named.ni_dvp); if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat) @@ -1338,6 +1338,7 @@ nd->nd_repstat = nfsvno_removesub(&named, 0, nd->nd_cred, p, exp); } + nfsrv_auditpath(NULL, named.ni_dvp, named.ni_cnd.cn_pnbuf, NULL, 1); } if (!(nd->nd_flag & ND_NFSV2)) { if (dirp) { @@ -1684,12 +1685,10 @@ if (!nd->nd_repstat) { if (dirp != NULL) dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred, - p); + p); nfsrvd_symlinksub(nd, &named, &nva, fhp, vpp, dirp, &dirfor, &diraft, &diraft_ret, NULL, NULL, p, exp, pathcp, pathlen); - if (named.ni_vp != NULL) - AUDIT_ARG_VNODE1(named.ni_vp); } else if (dirp != NULL) { dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred, p); vrele(dirp); @@ -1823,8 +1822,6 @@ */ nfsrvd_mkdirsub(nd, &named, &nva, fhp, vpp, dirp, &dirfor, &diraft, &diraft_ret, NULL, NULL, p, exp); - if (named.ni_vp != NULL) - AUDIT_ARG_VNODE1(named.ni_vp); if (nd->nd_flag & ND_NFSV3) { if (!nd->nd_repstat) { (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 1); ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdsocket.c#5 (text+ko) ==== @@ -345,113 +345,6 @@ NFSV4OP_COMMIT, }; -/* - * XXXgpf: should relocate them someplace else - * I just dont know where:S - */ -#define PARENTHINT 0x0001 -#define EXHAUSTSEARCH 0x0002 -#define WANTNAME 0x0004 - -/* - * XXXgpf: should probably relocate this function somewhere else as it's going to be called from various - * places in fs/nfsserver/ - * - * Do our best to acquire 'a' working path for vp - * - * vp - vnode in question - * dvp - directory with vp as a child - * fname - name used to reference vp inside dvp - * fhp - file handle for vp - * n - AUDIT_ARG_UPATH1 or AUDIT_ARG_UPATH2 - */ -static void -nfsrv_auditpath(struct vnode *vp, struct vnode *dvp, char *fname, fhandle_t *fhp, int n) -{ - char path[PATH_MAX]; - struct thread *td; - char *fullpath, *freepath; - char success; - - if (!AUDITING_TD(curthread)) - return; - - td = curthread; - freepath = NULL; - success = 0; - - /* try to find the path through vp */ - if (vp != NULL) { - /* try the cache */ - vn_fullpath_global(td, vp, &fullpath, &freepath); - if (freepath != NULL) { - success = 1; - goto out; - } - - /* if our cache fails us */ - if (fhp != NULL && vp->v_mount != NULL) { - uint64_t parent_hint; - /* get the hint stored inside the file handle */ - VFS_FHHINT(vp->v_mount, &fhp->fh_fid, &parent_hint); - vn_fullpath_nocache(vp, &fullpath, &freepath, - parent_hint, PARENTHINT | WANTNAME); - if (freepath != NULL) { - success = 1; - goto out; - } - } - } - - /* try to find the path through dvp and the component name used to reference vp */ - if (dvp != NULL && fname != NULL) { - /* try the cache */ - vn_fullpath_global(td, dvp, &fullpath, &freepath); - if (freepath != NULL) { - snprintf(path, sizeof(path), "%s/%s", fullpath, fname); - fullpath = path; - success = 1; - goto out; - } - - /* if our cache fails us */ - vn_fullpath_nocache(dvp, &fullpath, &freepath, - 0, WANTNAME); - if (freepath != NULL) { - snprintf(path, sizeof(path), "%s/%s", fullpath, fname); - fullpath = path; - success = 1; - goto out; - } - } - - /* last resort, just save the name used to reference the file in question */ - if (fname != NULL) { - strlcpy(path, fname, sizeof(path)); - fullpath = path; - success = 1; - } - -out: - if (success) { - switch (n) { - case 1: - AUDIT_ARG_UPATH1(td, fullpath); - break; - case 2: - AUDIT_ARG_UPATH2(td, fullpath); - break; - default: - AUDIT_ARG_UPATH1(td, fullpath); - break; - } - } - - if (freepath != NULL) { - free(freepath, M_TEMP); - } -} - /* * Do an RPC. Basically, get the file handles translated to vnode pointers * and then call the appropriate server routine. The server routines are @@ -465,6 +358,7 @@ { int error = 0; vnode_t vp; + vnode_t AUDIT_vp; mount_t mp = NULL; struct nfsrvfh fh; struct nfsexstuff nes; @@ -548,8 +442,14 @@ if (nfs_retfh[nd->nd_procnum] == 1) { if (vp) NFSVOPUNLOCK(vp, 0, p); + AUDIT_vp = NULL; error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram, - vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes); + vp, &AUDIT_vp, (fhandle_t *)fh.nfsrvfh_data, p, &nes); + if (AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 1); + vrele(AUDIT_vp); + } } else if (nfs_retfh[nd->nd_procnum] == 2) { error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram, vp, NULL, p, &nes, NULL); ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdsubs.c#2 (text+ko) ==== @@ -41,6 +41,7 @@ * copy data between mbuf chains and uio lists. */ #include +#include extern u_int32_t newnfs_true, newnfs_false; extern int nfs_pubfhset; @@ -2041,3 +2042,108 @@ return (1); } + +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + +/* + * XXXgpf: dont know if this is the right location for the function + * + * Do our best to acquire 'a' working path for vp + * + * vp - vnode in question + * dvp - directory with vp as a child + * fname - name used to reference vp inside dvp + * fhp - file handle for vp + * n - AUDIT_ARG_UPATH1 or AUDIT_ARG_UPATH2 + */ +void +nfsrv_auditpath(vnode_t vp, vnode_t dvp, char *fname, fhandle_t *fhp, int n) +{ + char path[PATH_MAX]; + struct thread *td; + char *fullpath, *freepath; + char success; + + if (!AUDITING_TD(curthread)) + return; + + td = curthread; + freepath = NULL; + success = 0; + + /* try to find the path through vp */ + if (vp != NULL) { + /* try the cache */ + vn_fullpath_global(td, vp, &fullpath, &freepath); + if (freepath != NULL) { + success = 1; + goto out; + } + /* if our cache fails us */ + if (fhp != NULL && vp->v_mount != NULL) { + uint64_t parent_hint; + /* get the hint stored inside the file handle */ + VFS_FHHINT(vp->v_mount, &fhp->fh_fid, &parent_hint); + vn_fullpath_nocache(vp, &fullpath, &freepath, + parent_hint, PARENTHINT | WANTNAME); + if (freepath != NULL) { + success = 1; + goto out; + } + } + } + + /* try to find the path through dvp and the component name used to reference vp */ + if (dvp != NULL && fname != NULL) { + /* try the cache */ + vn_fullpath_global(td, dvp, &fullpath, &freepath); + if (freepath != NULL) { + snprintf(path, sizeof(path), "%s/%s", fullpath, fname); + fullpath = path; + success = 1; + goto out; + } + + /* if our cache fails us */ + vn_fullpath_nocache(dvp, &fullpath, &freepath, + 0, WANTNAME); + if (freepath != NULL) { + snprintf(path, sizeof(path), "%s/%s", fullpath, fname); + fullpath = path; + success = 1; + goto out; + } + } + + /* last resort, just save the name used to reference the file in question */ + if (fname != NULL) { + strlcpy(path, fname, sizeof(path)); + fullpath = path; + success = 1; + } + +out: + if (success) { + switch (n) { + case 1: + AUDIT_ARG_UPATH1(td, fullpath); + break; + case 2: + AUDIT_ARG_UPATH2(td, fullpath); + break; + default: + AUDIT_ARG_UPATH1(td, fullpath); + break; + } + } + + if (freepath != NULL) { + free(freepath, M_TEMP); + } +}