Subject: eliminating veriexec #ifdefs in vfs_vnops.c
To: None <tech-kern@NetBSD.org>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 12/29/2006 14:46:19
This is a multi-part message in MIME format.
--------------010908070505040806050404
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
hi,
attached diff does, well, what the subject line says.
it works here, but I'd like some more eyes on it (locking issues? I
dunno), so please review.
if no one objects, I'll just go ahead and commit it.
-e.
--------------010908070505040806050404
Content-Type: text/plain;
name="openchk.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="openchk.diff"
Index: sys/verified_exec.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/verified_exec.h,v
retrieving revision 1.47
diff -u -p -r1.47 verified_exec.h
--- sys/verified_exec.h 26 Dec 2006 07:50:40 -0000 1.47
+++ sys/verified_exec.h 27 Dec 2006 22:38:43 -0000
@@ -122,6 +122,7 @@ int veriexec_removechk(struct vnode *, c
int veriexec_renamechk(struct vnode *, const char *, struct vnode *,
const char *, struct lwp *);
int veriexec_unmountchk(struct mount *);
+int veriexec_openchk(struct lwp *, struct nameidata *, int);
#endif /* _KERNEL */
#endif /* !_SYS_VERIFIED_EXEC_H_ */
Index: kern/vfs_vnops.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.129
diff -u -p -r1.129 vfs_vnops.c
--- kern/vfs_vnops.c 30 Nov 2006 01:09:47 -0000 1.129
+++ kern/vfs_vnops.c 27 Dec 2006 22:38:19 -0000
@@ -104,28 +104,11 @@ vn_open(struct nameidata *ndp, int fmode
kauth_cred_t cred = l->l_cred;
struct vattr va;
int error;
-#if NVERIEXEC > 0
- const char *pathbuf;
- char *tmppathbuf;
- boolean_t veriexec_monitored = FALSE;
-#endif /* NVERIEXEC > 0 */
#if NVERIEXEC > 0
- if (ndp->ni_segflg == UIO_USERSPACE) {
- tmppathbuf = PNBUF_GET();
- error = copyinstr(ndp->ni_dirp, tmppathbuf, MAXPATHLEN,
- NULL);
- if (error) {
- if (veriexec_verbose >= 1)
- log(LOG_NOTICE, "Veriexec: Can't copy path."
- " (error=%d)\n", error);
- goto bad2;
- }
- pathbuf = tmppathbuf;
- } else {
- tmppathbuf = NULL;
- pathbuf = ndp->ni_dirp;
- }
+ error = veriexec_openchk(l, ndp, fmode);
+ if (error)
+ return (error);
#endif /* NVERIEXEC > 0 */
restart:
@@ -138,20 +121,6 @@ restart:
if ((error = namei(ndp)) != 0)
goto bad2;
if (ndp->ni_vp == NULL) {
-#if NVERIEXEC > 0
- /* Lockdown mode: Prevent creation of new files. */
- if (veriexec_strict >= VERIEXEC_LOCKDOWN) {
- VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
-
- log(LOG_ALERT, "Veriexec: Preventing "
- "new file creation in %s.\n", pathbuf);
-
- vp = ndp->ni_dvp;
- error = EPERM;
- goto bad;
- }
-#endif /* NVERIEXEC > 0 */
-
VATTR_NULL(&va);
va.va_type = VREG;
va.va_mode = cmode;
@@ -206,12 +175,6 @@ restart:
}
if ((fmode & O_CREAT) == 0) {
-#if NVERIEXEC > 0
- if ((error = veriexec_verify(l, vp, pathbuf, VERIEXEC_FILE,
- &veriexec_monitored)) != 0)
- goto bad;
-#endif /* NVERIEXEC > 0 */
-
if (fmode & FREAD) {
if ((error = VOP_ACCESS(vp, VREAD, cred, l)) != 0)
goto bad;
@@ -225,45 +188,10 @@ restart:
if ((error = vn_writechk(vp)) != 0 ||
(error = VOP_ACCESS(vp, VWRITE, cred, l)) != 0)
goto bad;
-#if NVERIEXEC > 0
- if (veriexec_monitored) {
- veriexec_report("Write access request.",
- pathbuf, l, REPORT_ALWAYS|REPORT_ALARM);
-
- /* IPS mode: Deny writing to monitored files. */
- if (veriexec_strict >= VERIEXEC_IPS) {
- error = EPERM;
- goto bad;
- } else {
- veriexec_purge(vp);
- }
- }
-#endif /* NVERIEXEC > 0 */
}
}
if (fmode & O_TRUNC) {
-#if NVERIEXEC > 0
- if ((error = veriexec_verify(l, vp, pathbuf, VERIEXEC_FILE,
- &veriexec_monitored)) != 0) {
- /*VOP_UNLOCK(vp, 0);*/
- goto bad;
- }
-
- if (veriexec_monitored) {
- veriexec_report("Truncate access request.", pathbuf, l,
- REPORT_VERBOSE | REPORT_ALARM);
-
- /* IPS mode: Deny truncating monitored files. */
- if (veriexec_strict >= 2) {
- error = EPERM;
- goto bad;
- } else {
- veriexec_purge(vp);
- }
- }
-#endif /* NVERIEXEC > 0 */
-
VOP_UNLOCK(vp, 0); /* XXX */
if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0) {
@@ -294,11 +222,6 @@ bad:
vput(vp);
bad2:
-#if NVERIEXEC > 0
- if (tmppathbuf != NULL)
- PNBUF_PUT(tmppathbuf);
-#endif /* NVERIEXEC > 0 */
-
return (error);
}
Index: kern/kern_verifiedexec.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_verifiedexec.c,v
retrieving revision 1.87
diff -u -p -r1.87 kern_verifiedexec.c
--- kern/kern_verifiedexec.c 29 Dec 2006 11:34:14 -0000 1.87
+++ kern/kern_verifiedexec.c 28 Dec 2006 02:13:41 -0000
@@ -64,6 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_verifie
#include <sys/conf.h>
#include <miscfs/specfs/specdev.h>
#include <prop/proplib.h>
+#include <sys/fcntl.h>
MALLOC_DEFINE(M_VERIEXEC, "Veriexec", "Veriexec data-structures");
@@ -1229,3 +1230,70 @@ veriexec_unmountchk(struct mount *mp)
return (error);
}
+
+int
+veriexec_openchk(struct lwp *l, struct nameidata *ndp, int fmode)
+{
+ struct vnode *vp;
+ pathname_t pn = NULL;
+ boolean_t monitored = FALSE;
+ int error;
+
+ ndp->ni_cnd.cn_nameiop = LOOKUP;
+ ndp->ni_cnd.cn_flags = LOCKLEAF;
+ if (!(fmode & O_EXCL) && !(fmode & O_NOFOLLOW))
+ ndp->ni_cnd.cn_flags |= FOLLOW;
+ error = namei(ndp);
+ vp = error ? NULL : ndp->ni_vp;
+ if (error && (error != ENOENT))
+ goto out;
+
+ error = pathname_get(ndp->ni_dirp, ndp->ni_segflg, &pn);
+ if (error) {
+ if (veriexec_verbose >= 1)
+ log(LOG_NOTICE, "Veriexec: Can't copy path. "
+ "(error=%d)\n", error);
+ goto out;
+ }
+
+ if (vp == NULL) {
+ /* If no creation requested, let this fail normally. */
+ if (!(fmode & O_CREAT)) {
+ error = 0;
+ goto out;
+ }
+
+ /* Lockdown mode: Prevent creation of new files. */
+ if (veriexec_strict >= VERIEXEC_LOCKDOWN) {
+ log(LOG_ALERT, "Veriexec: Preventing new file "
+ "creation in `%s'.\n", pathname_path(pn));
+ error = EPERM;
+ }
+
+ goto out;
+ }
+
+ error = veriexec_verify(l, vp, pathname_path(pn), VERIEXEC_FILE,
+ &monitored);
+ if (error)
+ goto out;
+
+ if (monitored && ((fmode & FWRITE) || (fmode & O_TRUNC))) {
+ veriexec_report("Write access request.", pathname_path(pn), l,
+ REPORT_ALWAYS | REPORT_ALARM);
+
+ /* IPS mode: Deny writing to/truncating monitored files. */
+ if (veriexec_strict >= VERIEXEC_IPS)
+ error = EPERM;
+ else
+ veriexec_purge(vp);
+ }
+
+ out:
+ if (vp != NULL)
+ vput(vp);
+
+ pathname_put(pn);
+
+ return (error);
+}
--------------010908070505040806050404--