PERFORCE change 180201 for review
Efstratios Karatzas
gpf at FreeBSD.org
Fri Jun 25 00:46:38 UTC 2010
http://p4web.freebsd.org/@@180201?ac=10
Change 180201 by gpf at 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);
+ }
+}
More information about the p4-projects
mailing list