DragonFlyBSD Kernel Audit
DF-0834 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/ufs/ufs_lookup.c b/sys/vfs/ufs/ufs_lookup.c
--- a/sys/vfs/ufs/ufs_lookup.c
+++ b/sys/vfs/ufs/ufs_lookup.c
@@ -1105,6 +1105,8 @@
 	return (1);
 }
 
+#define	UFS_CHECKPATH_MAXDEPTH	64	/* sane bound on .. chain length */
+
 /*
  * Check if source directory is in the path of the target directory.
  * Target is supplied locked, source is unlocked.
@@ -1114,7 +1116,7 @@
 ufs_checkpath(struct inode *source, struct inode *target, struct ucred *cred)
 {
 	struct vnode *vp;
-	int error, rootino, namlen;
+	int error, rootino, namlen, depth = 0;
 	struct dirtemplate dirbuf;
 
 	vp = ITOV(target);
@@ -1128,6 +1130,10 @@
 		goto out;
 
 	for (;;) {
+		if (++depth > UFS_CHECKPATH_MAXDEPTH) {
+			error = ENOTDIR;			/* .. chain too long or cyclic */
+			break;
+		}
 		if (vp->v_type != VDIR) {
 			error = ENOTDIR;
 			break;