Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Jun 2010 00:46:36 GMT
From:      Efstratios Karatzas <gpf@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 180201 for review
Message-ID:  <201006250046.o5P0ka6K099312@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <fs/nfs/nfsport.h>
+#include <security/audit/audit.h>
 
 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);
+	}
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006250046.o5P0ka6K099312>