DragonFlyBSD Kernel Audit
DF-0824 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/ext2fs/ext2_lookup.c b/sys/vfs/ext2fs/ext2_lookup.c
--- a/sys/vfs/ext2fs/ext2_lookup.c
+++ b/sys/vfs/ext2fs/ext2_lookup.c
@@ -1187,6 +1187,8 @@
 	return (1);
 }
 
+#define	EXT2_CHECKPATH_MAXDEPTH	256	/* sane bound on .. chain length */
+
 /*
  * Check if source directory is in the path of the target directory.
  * Target is supplied locked, source is unlocked.
@@ -1196,7 +1198,7 @@
 ext2_checkpath(struct inode *source, struct inode *target, struct ucred *cred)
 {
 	struct vnode *vp;
-	int error, namlen;
+	int error, namlen, depth = 0;
 	struct dirtemplate dirbuf;
 
 	vp = ITOV(target);
@@ -1210,6 +1212,10 @@
 	}
 
 	for (;;) {
+		if (depth++ >= EXT2_CHECKPATH_MAXDEPTH) {
+			error = EINVAL;	/* .. chain too long or cyclic */
+			break;
+		}
 		if (vp->v_type != VDIR) {
 			error = ENOTDIR;
 			break;